python如何使用包里的类的方法_如何包装类的每个方法?

Michael Foord的Voidspace博客在一篇题为A Method Decorating Metaclass的文章中描述了一种优雅的方法,该文章介绍了什么是元类以及如何使用它们。将其稍微简化并应用到您的情况中,结果是:from types import FunctionType

from functools import wraps

def wrapper(method):

@wraps(method)

def wrapped(*args, **kwrds):

# ...

return wrapped

class MetaClass(type):

def __new__(meta, classname, bases, classDict):

newClassDict = {}

for attributeName, attribute in classDict.items():

if isinstance(attribute, FunctionType):

# replace it with a wrapped version

attribute = wrapper(attribute)

newClassDict[attributeName] = attribute

return type.__new__(meta, classname, bases, newClassDict)

class MyClass(object):

__metaclass__ = MetaClass # wrap all the methods

def method1(self, ...):

# ...etc ...

在Python中,函数/方法装饰器只是函数包装器加上一些语法糖,使使用它们更容易(而且更漂亮)。

Python 3兼容性更新

前面的代码使用了Python2.x元类语法,为了在Python3.x中使用,需要对其进行翻译,但是在前面的版本中它将不再工作。这意味着它需要使用:class MyBase(metaclass=MetaClass)

...

而不是:class MyBase(object):

__metaclass__ = MetaClass"

...

如果需要,可以编写同时兼容Python2.x和3.x的代码,但这样做需要使用稍微复杂一点的技术,动态创建继承所需元类的新基类,从而避免由于Python的两个版本之间的语法差异而导致的错误。这基本上就是Benjamin Peterson的six模块的^{}函数所做的。from types import FunctionType

from functools import wraps

def wrapper(method):

@wraps(method)

def wrapped(*args, **kwrds):

print('{!r} executing'.format(method.__name__))

return method(*args, **kwrds)

return wrapped

class MetaClass(type):

def __new__(meta, classname, bases, classDict):

newClassDict = {}

for attributeName, attribute in classDict.items():

if isinstance(attribute, FunctionType):

# replace it with a wrapped version

attribute = wrapper(attribute)

newClassDict[attributeName] = attribute

return type.__new__(meta, classname, bases, newClassDict)

def with_metaclass(meta):

""" Create an empty class with the supplied bases and metaclass. """

return type.__new__(meta, "TempBaseClass", (object,), {})

if __name__ == '__main__':

# Inherit metaclass from a dynamically-created base class.

class MyClass(with_metaclass(MetaClass)):

@staticmethod

def a_static_method():

pass

@classmethod

def a_class_method(cls):

pass

def a_method(self):

pass

instance = MyClass()

instance.a_static_method() # Not decorated.

instance.a_class_method() # Not decorated.

instance.a_method() # -> 'a_method' executing

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值