How to Get All Methods of a Class

How do I get list of methods in a Python class?

An example (listing the methods of the optparse.OptionParser class):

>>> from optparse import OptionParser
>>> import inspect
#python2
>>> inspect.getmembers(OptionParser, predicate=inspect.ismethod)
[([('__init__', <unbound method OptionParser.__init__>),
...
('add_option', <unbound method OptionParser.add_option>),
('add_option_group', <unbound method OptionParser.add_option_group>),
('add_options', <unbound method OptionParser.add_options>),
('check_values', <unbound method OptionParser.check_values>),
('destroy', <unbound method OptionParser.destroy>),
('disable_interspersed_args',
<unbound method OptionParser.disable_interspersed_args>),
('enable_interspersed_args',
<unbound method OptionParser.enable_interspersed_args>),
('error', <unbound method OptionParser.error>),
('exit', <unbound method OptionParser.exit>),
('expand_prog_name', <unbound method OptionParser.expand_prog_name>),
...
]
# python3
>>> inspect.getmembers(OptionParser, predicate=inspect.isfunction)
...

Notice that getmembers returns a list of 2-tuples. The first item is the name of the member, the second item is the value.

You can also pass an instance to getmembers:

>>> parser = OptionParser()
>>> inspect.getmembers(parser, predicate=inspect.ismethod)
...

Get functions (methods) of a class

This function will get all functions. Inherited or not, enumerable or not. All functions are included.

function getAllFuncs(toCheck) {
const props = [];
let obj = toCheck;
do {
props.push(...Object.getOwnPropertyNames(obj));
} while (obj = Object.getPrototypeOf(obj));

return props.sort().filter((e, i, arr) => {
if (e!=arr[i+1] && typeof toCheck[e] == 'function') return true;
});
}

Do test

getAllFuncs([1,3]);

console output:

["constructor", "toString", "toLocaleString", "join", "pop", "push", "concat", "reverse", "shift", "unshift", "slice", "splice", "sort", "filter", "forEach", "some", "every", "map", "indexOf", "lastIndexOf", "reduce", "reduceRight", "entries", "keys", "constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "__defineGetter__", "__lookupGetter__", "__defineSetter__", "__lookupSetter__"]

Note

It doesn't return functions defined via symbols;

Can I get all methods of a class?

To know about all methods use this statement in console:

javap -cp jar-file.jar packagename.classname

or

javap class-file.class packagename.classname

or for example:

javap java.lang.StringBuffer

Can i get all methods of a python object?

you need see inspect. For example

inspect.getmembers(object, inspect.ismethod)

it returns only method.

Getting all class methods in classes in current file in Python?

On Python 3, calling inspect.ismethod on an attribute of a class that happens to be a function will always be False, because it will just be a plain function. function.__get__ only returns a method object when accessed as an attribute of an instance.

If you want to get all "methods" of the class just use inspect.isfunction.

>>> class A:
... def __init__(self): pass
...
>>> A.__init__
<function A.__init__ at 0x7fd524dd2f80>
>>> inspect.ismethod(A.__init__)
False
>>> inspect.isfunction(A.__init__)
True
>>> inspect.ismethod(A().__init__)
True

Finding what methods a Python object has

For many objects, you can use this code, replacing 'object' with the object you're interested in:

object_methods = [method_name for method_name in dir(object)
if callable(getattr(object, method_name))]

I discovered it at diveintopython.net (now archived), that should provide some further details!

If you get an AttributeError, you can use this instead:

getattr() is intolerant of pandas style Python 3.6 abstract virtual sub-classes. This code does the same as above and ignores exceptions.

import pandas as pd
df = pd.DataFrame([[10, 20, 30], [100, 200, 300]],
columns=['foo', 'bar', 'baz'])
def get_methods(object, spacing=20):
methodList = []
for method_name in dir(object):
try:
if callable(getattr(object, method_name)):
methodList.append(str(method_name))
except Exception:
methodList.append(str(method_name))
processFunc = (lambda s: ' '.join(s.split())) or (lambda s: s)
for method in methodList:
try:
print(str(method.ljust(spacing)) + ' ' +
processFunc(str(getattr(object, method).__doc__)[0:90]))
except Exception:
print(method.ljust(spacing) + ' ' + ' getattr() failed')

get_methods(df['foo'])

Get the list of methods of a class

No this is not possible in a general way. C++ does not have the same metadata infrastructure that .Net posses.

Could you provide us with a scenario where you want to use this information? There may be a better approach you can use with C++

How to create a type that extract all methods from a class in typescript?

Let's write a type function PickMatching<T, V> which takes an object type T and a property value type V and evaluates to another object type only those properties of T whose property types are assignable to V. This is straightforward if we use key remapping in mapped types:

type PickMatching<T, V> =
{ [K in keyof T as T[K] extends V ? K : never]: T[K] }

By mapping a key to never we are essentially omitting the property from the mapped type. Then we can express ExtractMethods<T> by picking all function-valued properties from T:

type ExtractMethods<T> = PickMatching<T, Function>;

This produces the following results:

class Foo {
bar() { }
baz() { }
notAMethod = 123;
funcProp = () => 10;
}

type FooMethod = ExtractMethods<Foo>
/* type FooMethod = {
bar: () => void;
baz: () => void;
funcProp: () => number;
} */

As you see, the number-typed notAMethod is not present in FooMethod. The methods bar() and baz() appear in FooMethod as desired. Importantly, the function-typed funcProp is also present in FooMethod. The type system cannot reliably distinguish a method from a function-valued property. The main difference is whether or not the member exists on the instance directly or on the class prototype, but the type system treats class instances and class prototypes as the same type.

That's really the best you can do to implement ExtractMethods generally.


On the other hand, if you want to do it just for a particular class like Foo and can drop down from the type level to the value level, you can use the fact that the compiler understands that spreading an instance of a class into a new object will only give you the instance properties:

const spreadFoo = { ... new Foo() };
/* const spreadFoo: {
notAMethod: number;
funcProp: () => number;
} */

and from that you can compute FooMethod (assuming that you don't have any non-method prototype members):

type FooMethod = Omit<Foo, keyof typeof spreadFoo>;
/* type FooMethod = {
bar: () => void;
baz: () => void;
} */

But it depends on your use cases whether or not this sort of approach is feasible.

Playground link to code

What is the new way of getting all methods of a class, including inherited default methods of Java 8?

Even for the “Before Java 8” scenario, your code snippet isn’t correct. But collecting all methods isn’t a usual scenario though, as you normally need methods regarding a certain context, e.g. you might want to know which methods are accessible for a given context, which doesn’t include all methods, even if you consider non-public methods. If you really want all methods, you have to recall that private and static methods are never overridden and package-private methods are only overridden when being declared within the same package. So it’s not correct to filter every encountered method signature.

What makes matters worse is that methods might get overridden with different modifiers. The latter can be solved by keeping the idea to start at the actual class and use Class.getMethods() to get all public method including default methods and traverse the superclass hierarchy towards java.lang.Object so the already encountered overrides have the least restrictive access modifiers.

As a side note, nesting linear search loops is never a good idea. You’ll soon end up with a quadratic or worse complexity.

You may collect methods using the following method:

public static Set<Method> getAllMethods(Class<?> cl) {
Set<Method> methods=new LinkedHashSet<>();
Collections.addAll(methods, cl.getMethods());
Map<Object,Set<Package>> types=new HashMap<>();
final Set<Package> pkgIndependent = Collections.emptySet();
for(Method m: methods) types.put(methodKey(m), pkgIndependent);
for(Class<?> current=cl; current!=null; current=current.getSuperclass()) {
for(Method m: current.getDeclaredMethods()) {
final int mod = m.getModifiers(),
access=Modifier.PUBLIC|Modifier.PROTECTED|Modifier.PRIVATE;
if(!Modifier.isStatic(mod)) switch(mod&access) {
case Modifier.PUBLIC: continue;
default:
Set<Package> pkg=
types.computeIfAbsent(methodKey(m), key -> new HashSet<>());
if(pkg!=pkgIndependent && pkg.add(current.getPackage())) break;
else continue;
case Modifier.PROTECTED:
if(types.putIfAbsent(methodKey(m), pkgIndependent)!=null) continue;
// otherwise fall-through
case Modifier.PRIVATE:
}
methods.add(m);
}
}
return methods;
}

private static Object methodKey(Method m) {
return Arrays.asList(m.getName(),
MethodType.methodType(m.getReturnType(), m.getParameterTypes()));
}

But as said, it might be the case that it isn’t suitable for whatever you want to do. You should ask yourself the following questions first:

  • Are you looking for methods that make up the API (that’s usually public and protected only)?
  • Or do you want to actually see methods accessible for a certain class/package context?
  • Shall static methods be included?
  • Shall synthetic/bridge methods be included?
  • etc.

Here is the revised method adapted to your more specific request:

public static Collection<Method> getAllMethods(Class clazz,
boolean includeAllPackageAndPrivateMethodsOfSuperclasses,
boolean includeOverridenAndHidden) {

Predicate<Method> include = m -> !m.isBridge() && !m.isSynthetic() &&
Character.isJavaIdentifierStart(m.getName().charAt(0))
&& m.getName().chars().skip(1).allMatch(Character::isJavaIdentifierPart);

Set<Method> methods = new LinkedHashSet<>();
Collections.addAll(methods, clazz.getMethods());
methods.removeIf(include.negate());
Stream.of(clazz.getDeclaredMethods()).filter(include).forEach(methods::add);

final int access=Modifier.PUBLIC|Modifier.PROTECTED|Modifier.PRIVATE;

Package p = clazz.getPackage();
if(!includeAllPackageAndPrivateMethodsOfSuperclasses) {
int pass = includeOverridenAndHidden?
Modifier.PUBLIC|Modifier.PROTECTED: Modifier.PROTECTED;
include = include.and(m -> { int mod = m.getModifiers();
return (mod&pass)!=0
|| (mod&access)==0 && m.getDeclaringClass().getPackage()==p;
});
}
if(!includeOverridenAndHidden) {
Map<Object,Set<Package>> types = new HashMap<>();
final Set<Package> pkgIndependent = Collections.emptySet();
for(Method m: methods) {
int acc=m.getModifiers()&access;
if(acc==Modifier.PRIVATE) continue;
if(acc!=0) types.put(methodKey(m), pkgIndependent);
else types.computeIfAbsent(methodKey(m),x->new HashSet<>()).add(p);
}
include = include.and(m -> { int acc = m.getModifiers()&access;
return acc!=0? acc==Modifier.PRIVATE
|| types.putIfAbsent(methodKey(m), pkgIndependent)==null:
noPkgOverride(m, types, pkgIndependent);
});
}
for(clazz=clazz.getSuperclass(); clazz!=null; clazz=clazz.getSuperclass())
Stream.of(clazz.getDeclaredMethods()).filter(include).forEach(methods::add);
return methods;
}
static boolean noPkgOverride(
Method m, Map<Object,Set<Package>> types, Set<Package> pkgIndependent) {
Set<Package> pkg = types.computeIfAbsent(methodKey(m), key -> new HashSet<>());
return pkg!=pkgIndependent && pkg.add(m.getDeclaringClass().getPackage());
}
private static Object methodKey(Method m) {
return Arrays.asList(m.getName(),
MethodType.methodType(m.getReturnType(), m.getParameterTypes()));
}


Related Topics



Leave a reply



Submit