python - 装饰一个类 - 装饰一次就忘记了?

标签 python decorator interpreter

我成功创建了一个装饰器,可以装饰任何类型的类,为它们添加一个标准接口(interface),以便于访问、集成等......

我一直拒绝使用元类,因为关于这一点的文献表明它是一种矫枉过正的行为,而且大多数时候可以用类装饰器来代替。令我困扰的是以下几点:

def Decorator(somearg):

    def wrapper(cls):
        clsinit = cls.__init__
        cls.members = []

        def __init__(self, *args, **kwargs):
            #do something with somearg...
            self.__class__.members.append(self)
            clsinit(self,*args,**kwargs)

        cls.__init__ = clsinit
        return cls

    return wrapper

@Decorator('thearg')
class A(object):
    pass

a = A()
b = A()

使用 python 调试器,在导入时,类 A 立即用参数“thearg”修饰。但每次我实例化 A() 时,实例都会直接调用装饰器中定义的 init,而不经过前面的层。这很好,因为我希望我的类记录每个成员,而不是在每次实例化新实例时重置。但我不确定我明白为什么。

有人可以解释一下在这个特定情况下Python解释器的物理原理吗?

最佳答案

如果您只是更改类而不是创建新类,则不需要包装函数(应该是包装类):

def Decorator(cls):
    clsinit = cls.__init__
    cls.members = []

    def __init__(self, *args, **kwargs):
        clsinit(self, *args, **kwargs)
        self.__class__.members.append(self)

    cls.__init__ = __init__
    return cls

顺便说一句,您应该只创建一个基类并从中继承:

class Base(object):
    members = []
    def __init__(self):
        self.__class__.members.append(self)

class A(Base):
    pass

干净多了

关于python - 装饰一个类 - 装饰一次就忘记了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14784474/

相关文章:

python - 在 python 中使用 re.sub 将 "&&"替换为 "and"。

python - 将输入附加到现有列表

python - 新添加的数据库条目在其他模型中不可见

apache-spark - Spark Interpreter 在 Zeppelin 中不起作用

python - 我的数据框有很多(192)列。如何同时选择两列?

python - 如何编写 Python 装饰器来增加堆栈深度?

python - Python 中的装饰器。如何检查args类型

python - 在类中定义装饰器,在类定义中也可用

c++ - 与编译器相比,为什么调试器在发生错误时更加具体?

python - Python解释器的输出?