Python 2.x 元类生成的包装器中断检查
我遇到一个问题,我使用元类包装了一些类方法,但现在如果我使用内置的 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
I'm having an issue where I have wrapped some class methods using a metaclass, but now if I use the help() built-in the methods are displayed as the wrapper instead of the original method.
# 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)
As you can see I have added the @functools.wraps decorator to the __wrapper method so that at least I get the proper method name, but I still don't get the proper arguments.
Example:
| Methods defined here:
|
| __init__(self, *args, **kwargs)
I've seen some articles suggesting monkey patching inspect.getargspec but I can't see this being a practical solution.
Anyone have any other black magic they could suggest?
Cheers,
CB
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论