我对Python很新。在最近对很多PHP进行编程时,我习惯于使用__get
和__set
“魔术”方法。只有当班级的公共变量不存在时才会调用它们。
我正在尝试在Python中复制相同的行为,但似乎失败了。鉴于似乎没有办法以C ++ / PHP方式实际定义类变量,当我尝试在我的类中通常使用变量时(即通过self),它最终调用__getattr__
!
如何定义我不希望受__getattr__
影响的班级属性?
我正在尝试做的一些示例代码如下所示,我希望self.Document
和self.Filename
不要调用__getattr__
。
感谢您的帮助!
class ApplicationSettings(object):
RootXml = '<?xml version="1.0"?><Settings></Settings>'
def __init__(self):
self.Document = XmlDocument()
self.Document.LoadXml(RootXml)
def Load(self, filename):
self.Filename = filename
self.Document.Load(filename)
def Save(self, **kwargs):
# Check if the filename property is present
if 'filename' in kwargs:
self.Filename = kwargs['filename']
self.Document.Save(self.Filename)
def __getattr__(self, attr):
return self.Document.Item['Settings'][attr].InnerText
def __setattr__(self, attr, value):
if attr in self.Document.Item['Settings']:
# If the setting is already in the XML tree then simply change its value
self.Document.Item['Settings'][attr].InnerText = value
else:
# Setting is not in the XML tree, create a new element and add it
element = self.Document.CreateElement(attr)
element.InnerText = value
self.Document.Item['Settings'].AppendChild(element)
答案 0 :(得分:1)
__getattr__
。简单的解决方案是将Document
和Filename
添加到类中,以便找到它。
class ApplicationSettings(object):
Document = None
Filename = None
RootXml = '<?xml version="1.0"?><Settings></Settings>'
...
答案 1 :(得分:0)
这里你真正需要的是descriptor。像这样挂钩__getattr__
和__setattr__
并不是真正推荐的方法。
答案 2 :(得分:0)
我会使用Properties。使用@property
装饰器使它看起来更好。
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
然后,您可以访问C.x
,它会自动调用x的getter,并在您分配给C.x
时自动调用x的setter。
答案 3 :(得分:0)
显然,如果我在__setattr__
中检查属性名称,那么我可以调用对象的__setattr__
来获取我想要正常使用的属性。这感觉很糟糕,但很有效。
def __setattr__(self, attr, value):
# Check for attributes we want to store normally
if attr == 'Document' or attr == 'Filename':
object.__setattr__(self, attr, value)
# If the setting is already in the XML tree then simply change its value
elif attr in self.Document.Item['Settings']:
self.Document.Item['Settings'][attr].InnerText = value
# Setting is not in the XML tree, create a new element and add it
else:
element = self.Document.CreateElement(attr)
element.InnerText = value
self.Document.Item['Settings'].AppendChild(element)