我一直在使用pygame和python,我希望能够在我的类的属性发生变化时调用函数。我目前的解决方案是:
class ExampleClass(parentClass):
def __init__(self):
self.rect = pygame.rect.Rect(0,0,100,100)
def __setattr__(self, name, value):
parentClass.__setattr__(self,name,value)
dofancystuff()
Firstclass = ExampleClass()
当我用Firsclass.rect = pygame.rect.Rect(0,0,100,100)
更改rect值时,这个工作正常并调用dofancystuff。但是,如果我说Firstclass.rect.bottom = 3
。 __setattr__
并没有调用dofancystuff。
所以我的问题是,我猜是如何拦截对子类属性的任何更改?
编辑:另外如果我以错误的方式解决这个问题,请告诉我在python方面我不是很了解。
答案 0 :(得分:4)
Firstclass.rect = <...>
的情况下,您的__setattr__
被调用。但是在Firstclass.rect.bottom = 3
的情况下,调用Rect实例的__setattr__
方法。我看到的唯一解决方案是创建一个pygame.rect.Rect的派生类,在其中覆盖__setattr__
方法。你也可以修补Rect类,但是出于好的理由不鼓励这样做。
答案 1 :(得分:1)
您可以尝试__getattr__
,应该在Firstclass.rect
上调用。
但请改为:为pygame.rect
创建一个单独的类(ExampleClass.rect
的子类?)。在该课程中实施__setattr__
。现在,您将被告知rect
ExampleClass
成员__setattr__
中设置的任何内容。您仍然可以在ExampleClass
中实现rect
(并且应该),现在只确保您实例化自己的Firstclass
类的版本...
BTW:不要调用你的对象{{1}},因为它看起来像一个类而不是一个对象......
答案 2 :(得分:1)
这不是回答问题,但它是相关的:
self.__dict__[name] = value
可能比
更好parentClass.__setattr__(self, name, value)
这是Python文档推荐的(setattr“&gt; http://docs.python.org/2/reference/datamodel.html?highlight = setattr#object。 setattr )并制作在一般情况下更有意义,因为它不假设任何关于parentClass setattr 的行为。
对于未经请求的建议,已经四年太晚了!
答案 3 :(得分:0)
我认为你遇到这个困难的原因应该比其他答案所提供的更多信息。
当你这样做时,问题是:
myObject.attribute.thing = value
您没有为属性分配值。代码等同于:
anAttribute = myObject.attribute
anAttribute.thing = value
正如myObject所见,你所做的就是获取属性;你没有设置属性。
制作您控制的属性的子类,并且可以定义__setattr__是一种解决方案。
另一种解决方案,如果你有很多不同类型的属性并且不想为所有这些属性创建许多单独的子类,那么可能有意义的是覆盖__getattribute__或__getattr__以将外观返回到属性在__setattr__方法中执行相关操作。我自己并没有尝试这样做,但我想你应该能够创建一个简单的外观类,它将作为任何对象的外观。
需要谨慎选择__getattribute__和__getattr__。有关信息,请参阅上一句中链接的文档,但基本上如果使用__getattr__,实际属性将以某种方式封装/混淆,以便__getattr__处理对它们的请求,如果使用__getattribute__,则必须检索属性通过调用基类。
如果你要做的就是确定是否有一些更新,那么这就太过分了。