94 lines
2.8 KiB
Python
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']
|