栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何包装一个类的每个方法?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何包装一个类的每个方法?

Michael
Foord的Voidspace博客的一个条目中介绍了一种优雅的实现方法,该条目在“方法修饰元类的方法”部分中介绍了什么是元类以及如何使用它们。稍微简化一下,然后将其应用于您的情况会导致以下结果:

from types import FunctionTypefrom functools import wrapsdef wrapper(method):    @wraps(method)    def wrapped(*args, **kwrds):    #   ... <do something to/with "method" or the result of calling it>    return wrappedclass 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兼容性更新

先前的代码使用Python 2.x元类语法,需要进行翻译才能在Python 3.x中使用,但是在先前的版本中将不再起作用。这意味着它将需要使用:

class MyClass(metaclass=metaClass)    ...

代替:

class MyClass(object):     __metaclass__ = metaClass"    ...

如果需要,可以编写与Python 2.x
3.x兼容的代码,但是这样做需要使用稍微复杂一些的技术,该技术可以动态创建一个继承所需元类的新基类,从而避免由于两个Python版本之间的语法差异。这基本上就是本杰明·彼得森的六个模块的

with_metaclass()
功能。

from types import FunctionTypefrom functools import wrapsdef wrapper(method):    @wraps(method)    def wrapped(*args, **kwrds):        print('{!r} executing'.format(method.__name__))        return method(*args, **kwrds)    return wrappedclass 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


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/637775.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号