Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中类装饰的实际用途是什么?_Python_Decorator - Fatal编程技术网

Python中类装饰的实际用途是什么?

Python中类装饰的实际用途是什么?,python,decorator,Python,Decorator,在Python2.6中,将“类修饰符”引入到语言中已经存在的Python函数修饰符中。我看不出这样的东西何时何地可以实际使用,我想知道使用类装饰器是否比不使用类装饰器来实现相同的结果在性能上有所提高。类装饰器有多种用途。一个对我有意义的案例是在发布者-订阅者系统中注册一个类,例如插件或事件,类似于: @register class MyPlugin(Plugin): pass or @recieves_notifications class Console: def print

在Python2.6中,将“类修饰符”引入到语言中已经存在的Python函数修饰符中。我看不出这样的东西何时何地可以实际使用,我想知道使用类装饰器是否比不使用类装饰器来实现相同的结果在性能上有所提高。

类装饰器有多种用途。一个对我有意义的案例是在发布者-订阅者系统中注册一个类,例如插件或事件,类似于:

@register
class MyPlugin(Plugin):
    pass
or

@recieves_notifications
class Console:
    def print(self, text):
        ...
另一种用法可能是,例如,编写单元测试时,可以在单个方法或整个unittest.TestCase类定义上使用@unittest.skipIf和@unittest.skipUnless。这使得为特定于平台的问题编写测试变得非常容易

Example from asyncio/test_selectors

# Some platforms don't define the select.kqueue object for these tests.
# On those platforms, this entire grouping of tests will be skipped.

@unittest.skipUnless(hasattr(selectors, 'KqueueSelector'),
                 "Test needs selectors.KqueueSelector)")
class KqueueSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn):
...

类装饰器是将类对象作为输入并将绑定到输入类名称的对象更改为函数输出的函数(通常您希望返回相同的类)。它们是继承和元类的替代方案,用于自定义类行为,它们的不同之处在于它们在类完全创建之后进行操作,而不是影响类创建过程。另一个区别是类装饰器不是继承的,这在某些情况下可能比元类更有利

def register_handlers(cls):
    token = 'handle_'
    cls.handler_dict = {k[len(token):] : getattr(cls,k) for k in dir(cls) if k.startswith(token)}
    return cls

@register_handlers
class Handler:
    def handle_input(self):
        pass

    def handle_output(self):
        pass

    def handle_error(self):
        pass
此外,类装饰器根本不需要修改类,它可以返回类并在某个地方注册:

game_objects = {}

def register_object(cls):
    game_objects[cls.__name__] = cls
    return cls

@register_object
class Chair:
    pass

@register_object
class Car:
    pass

我希望您能提供意见,说明为什么这个问题被否决。我不明白这怎么会被解释为高度基于观点。在我看来,这是一个非常好的问题。虽然这充分解释了函数装饰器,但我谈论的是类装饰器。现在检查:)答案在您的注册示例中,将
register\u对象
作为装饰器,而不是在类中的
\uuuuu init\uuuuu
函数中调用参数为
self
的函数,会有什么好处?init方法应用于实例,这适用于类本身。对于类似的行为,您必须使用元类的
\uuuuu new\uuuuu
方法。哦,这样就对类本身而不是对创建的类的任何实例调用decorator了吗?是的,decorator与
cls=decorator(cls)