我遇到了一个问题,即我使用元类包装了一些类方法,但现在如果我使用内置的help(),则方法将显示为包装而不是原始方法。
# Example:
class MetaBuilderModule(type):
@staticmethod
def time_method(method):
@functools.wraps(method)
def __wrapper(self, *args, **kwargs):
if self.__timingstatus__[method.__name__]:
return method(self, *args, **kwargs)
else:
# Set the timing status of the method to True so that we don't
# time any inherited methods.
self.__timingstatus__[method.__name__] = True
start = time.time()
finish = None
result = None
# Put the result behind a try / except so that if we get an error
# within the method we can still reset the timing status.
try:
result = method(self, *args, **kwargs)
except Exception:
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exception(exc_type, exc_value, exc_traceback)
self.__timingstatus__[method.__name__] = False
return False
finish = time.time()
sys.stdout.write('Instance method \'%s\' of BuilderModule class'
' took %0.3fs to execute.\n' %(method.__name__, (finish - start)))
# Reset the timing status.
self.__timingstatus__[method.__name__] = False
return result
return __wrapper
def __new__(cls, name, bases, attrs):
# Create the __timingstatus__ dictionary that helps stop timers being
# triggered by inherited methods.
attrs['__timingstatus__'] = dict()
for attr in ['__init__', 'run']:
attrs['__timingstatus__'][attr] = False
if not attr in attrs:
continue
attrs[attr] = cls.time_method(attrs[attr])
return super(MetaBuilderModule, cls).__new__(cls, name, bases, attrs)
正如你所看到的,我已经将@ functools.wraps装饰器添加到__wrapper方法中,这样至少我得到了正确的方法名称,但我仍然没有得到正确的参数。
Example:
| Methods defined here:
|
| __init__(self, *args, **kwargs)
我看过一些文章建议修补猴子 inspect.getargspec ,但我不认为这是一个实用的解决方案。
任何人都可以提出任何其他黑魔法吗?
干杯,
CB