def classMethods(the_class,class_only=False,instance_only=False,exclude_internal=True):
def acceptMethod(tup):
#internal function that analyzes the tuples returned by getmembers tup[1] is the
#actual member object
is_method = inspect.ismethod(tup[1])
if is_method:
bound_to = tup[1].im_self
internal = tup[1].im_func.func_name[:2] == '__' and tup[1].im_func.func_name[-2:] == '__'
if internal and exclude_internal:
include = False
else:
include = (bound_to == the_class and not instance_only) or (bound_to == None and not class_only)
else:
include = False
return include
#uses filter to return results according to internal function and arguments
return filter(acceptMethod,inspect.getmembers(the_class))
from types import FunctionType
class Foo:
def bar(self): pass
def baz(self): pass
def methods(cls):
return [x for x, y in cls.__dict__.items() if type(y) == FunctionType]
methods(Foo) # ['bar', 'baz']
class CPerson:
def __init__(self, age):
self._age = age
def run(self):
pass
@property
def age(self): return self._age
@staticmethod
def my_static_method(): print("Life is short, you need Python")
@classmethod
def say(cls, msg): return msg
test_class = CPerson
# print(dir(test_class)) # list all the fields and methods of your object
print([(name, t) for name, t in test_class.__dict__.items() if type(t).__name__ == 'function' and not name.startswith('__')])
print([(name, t) for name, t in test_class.__dict__.items() if type(t).__name__ != 'function' and not name.startswith('__')])
输出
[('run', <function CPerson.run at 0x0000000002AD3268>)]
[('age', <property object at 0x0000000002368688>), ('my_static_method', <staticmethod object at 0x0000000002ACBD68>), ('say', <classmethod object at 0x0000000002ACF0B8>)]
class Ghost:
def boo(self, who):
return f'Who you gonna call? {who}'
我们可以检查实例检索
>>> g = Ghost()
>>> methods = [getattr(g, m) for m in dir(g) if not m.startswith('__')]
>>> print(methods)
[<bound method Ghost.boo of <__main__.Ghost object at ...>>]
所以你可以马上调用它:
>>> for method in methods:
... print(method('GHOSTBUSTERS'))
...
Who you gonna call? GHOSTBUSTERS
def method_finder(classname):
non_magic_class = []
class_methods = dir(classname)
for m in class_methods:
if m.startswith('__'):
continue
else:
non_magic_class.append(m)
return non_magic_class
method_finder(list)
import inspect
class ClassWithMethods:
def method1(self):
print('method1')
def method2(self):
print('method2')
obj=ClassWithMethods()
method_names = [attr for attr in dir(obj) if inspect.ismethod(getattr(obj,attr))
print(method_names)
输出:
[[('method1', <bound method ClassWithMethods.method1 of <__main__.ClassWithMethods object at 0x00000266779AF388>>), ('method2', <bound method ClassWithMethods.method2 of <__main__.ClassWithMethods object at 0x00000266779AF388>>)]]
class MethodAnalyzer:
class_under_test = None
@classmethod
def get_static_methods(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if isinstance(v, staticmethod)
}
return {}
@classmethod
def get_class_methods(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if isinstance(v, classmethod)
}
return {}
@classmethod
def get_instance_methods(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if callable(v) and not isinstance(v, classmethod)
}
return {}
@classmethod
def get_properties(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if isinstance(v, property)
}
return {}