Python 2.x元类生成包装器中断检查

时间:2011-10-12 06:02:19

标签: python python-2.x metaclass

我遇到了一个问题,即我使用元类包装了一些类方法,但现在如果我使用内置的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

0 个答案:

没有答案