Python类的装饰器

3
我尝试这样做:
import unittest

def decorator(cls):
    class Decorator(cls):
        def __init__(self, *args, **kwargs):
            super(Decorator, self).__init__(*args, **kwargs)

    return Decorator

@decorator
class myClass(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(myClass, self).__init__(*args, **kwargs)
        self.test = 'test'

    def test_test(self):
        pass


myClass().run()

但是我在MyClass.__init__中遇到了递归。有没有方法可以避免这种情况发生?


2
提示给楼主:如果您在这里粘贴了简化的代码,请确保它仍然显示您要解决的问题。在这种情况下,只需将发布的代码粘贴到交互式Python中并尝试一下即可。 - Alfe
我已经将我的代码更新到问题版本。 - Eugene
1
作为“类装饰器”,decorator应该扮演什么角色? - Jon Clements
为什么你不使用setUp而是覆盖__init__ - erb
它为不同的unittest.TestCase子类添加了额外的setUp()方法步骤。 - Eugene
1个回答

7
在装饰器类中,您无法以这种方式使用super(myClass, self)myClass被查找为全局变量,并且全局的myClass会被重新绑定到Decorator,因此您告诉Python从Decorator开始在类MRO中查找__init__,它是myClass,它调用super(myClass, self).__init__(),查找全局的myClass,它被绑定到Decorator等等。
最简单的解决方法是不要在这里使用super()
@decorator
class myClass(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        unittest.TestCase.__init__(self, *args, **kwargs)
        self.test = 'test'

这是 Python 3 中引入无参数版本的 super() 的一个原因之一,它给方法提供了一个 __class__ 单元。你可以通过一些非常棘手的方法来重新编译 myClass.__init__() 方法,使其绑定到原始未修饰的类对象上的 myClass 闭包,但对于单元测试,我不会费心去做这些。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接