是否有办法告诉(拦截)类属性的修改?

问题描述 投票:0回答:1

Python的新手,试图解决一个需要实现一个类装饰器的问题,该装饰器将跟踪其类和实例属性的更改。装饰器需要将get_change属性添加到所有类和实例属性,以跟踪其与初始值,修改值和已删除属性相对应的状态(INIT,MODIFIED,DELETED)。在大多数情况下,我解决了一个例外情况:修改,删除类属性。

@change_detection
class Struct(object):
    x = 42

    def __init__(self, y=0):
        self.y = y

a = Struct(11)

a.x == Struct.x == 42 # True
a.y == 11 # True

a.x.get_change == Struct.x.get_change == "INIT" # True
a.y.get_change == "INIT" # True

a.x = 100
a.x.get_change == "MOD" # True

del a.x
a.x.get_change == "DEL" # True

我对类属性保持不变,如更改:

Struct.x = 10
Struct.x.get_change == "MOD" # False - I don't know how to intercept setting the class attribute
del Struct.x
Struct.x.get_change == "DEL" # False - same as before

所以,您如何拦截类设置,属性删除?对于实例级别,您有__setattr____delattr__,但是类级别的等效项(如果有)是什么?

谢谢!

python python-3.x metaprogramming
1个回答
0
投票

[据我所知,没有一种魔术方法可以处理类属性。您可以改为执行以下操作:

class Verifier:
    def __init__(self, obj):
        self.obj = obj
        self.init = obj.__dict__.copy()

    def get_change(self, var):
        if var not in self.obj.__dict__:
            return "DEL"
        elif self.obj.__dict__[var] == self.init[var]:
            return "INIT"
        elif self.obj.__dict__[var] != self.init[var]:
            return "MOD"

class Struct:
    x = 42

verifier = Verifier(Struct)

这将允许以下操作:

Struct.x = 42
print(verifier.get_change("x")) # INIT

Struct.x = 43
print(verifier.get_change("x")) # MOD

del Struct.x
print(verifier.get_change("x")) # DEL

但是,请注意,这会中断:

Struct.y = 40
print(verifier.get_change("y"))
Traceback (most recent call last):
  File "test.py", line 26, in <module>
    print(verifier.get_change("y"))
  File "test.py", line 9, in get_change
    elif self.obj.__dict__[var] == self.init[var]:
KeyError: 'y'

因为我们的Verifier仅可以访问没有Struct变量的较早的y

© www.soinside.com 2019 - 2024. All rights reserved.