RosettaCodeData/Task/Reflection-List-methods/Python/reflection-list-methods.py

94 lines
2.8 KiB
Python

import inspect
# Sample classes for inspection
class Super(object):
def __init__(self, name):
self.name = name
def __str__(self):
return "Super(%s)" % (self.name,)
def doSup(self):
return 'did super stuff'
@classmethod
def cls(cls):
return 'cls method (in sup)'
@classmethod
def supCls(cls):
return 'Super method'
@staticmethod
def supStatic():
return 'static method'
class Other(object):
def otherMethod(self):
return 'other method'
class Sub(Other, Super):
def __init__(self, name, *args):
super(Sub, self).__init__(name);
self.rest = args;
self.methods = {}
def __dir__(self):
return list(set( \
sum([dir(base) for base in type(self).__bases__], []) \
+ type(self).__dict__.keys() \
+ self.__dict__.keys() \
+ self.methods.keys() \
))
def __getattr__(self, name):
if name in self.methods:
if callable(self.methods[name]) and self.methods[name].__code__.co_argcount > 0:
if self.methods[name].__code__.co_varnames[0] == 'self':
return self.methods[name].__get__(self, type(self))
if self.methods[name].__code__.co_varnames[0] == 'cls':
return self.methods[name].__get__(type(self), type)
return self.methods[name]
raise AttributeError("'%s' object has no attribute '%s'" % (type(self).__name__, name))
def __str__(self):
return "Sub(%s)" % self.name
def doSub():
return 'did sub stuff'
@classmethod
def cls(cls):
return 'cls method (in Sub)'
@classmethod
def subCls(cls):
return 'Sub method'
@staticmethod
def subStatic():
return 'Sub method'
sup = Super('sup')
sub = Sub('sub', 0, 'I', 'two')
sub.methods['incr'] = lambda x: x+1
sub.methods['strs'] = lambda self, x: str(self) * x
# names
[method for method in dir(sub) if callable(getattr(sub, method))]
# instance methods
[method for method in dir(sub) if callable(getattr(sub, method)) and hasattr(getattr(sub, method), '__self__') and getattr(sub, method).__self__ == sub]
#['__dir__', '__getattr__', '__init__', '__str__', 'doSub', 'doSup', 'otherMethod', 'strs']
# class methods
[method for method in dir(sub) if callable(getattr(sub, method)) and hasattr(getattr(sub, method), '__self__') and getattr(sub, method).__self__ == type(sub)]
#['__subclasshook__', 'cls', 'subCls', 'supCls']
# static & free dynamic methods
[method for method in dir(sub) if callable(getattr(sub, method)) and type(getattr(sub, method)) == type(lambda:nil)]
#['incr', 'subStatic', 'supStatic']
# names & values; doesn't include wrapped, C-native methods
inspect.getmembers(sub, predicate=inspect.ismethod)
# names using inspect
map(lambda t: t[0], inspect.getmembers(sub, predicate=inspect.ismethod))
#['__dir__', '__getattr__', '__init__', '__str__', 'cls', 'doSub', 'doSup', 'otherMethod', 'strs', 'subCls', 'supCls']