[英]Python - How to define attributes not affected by __getattr__?
我對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)
只有當Python無法在實例本身或其任何基類中找到該屬性時,才會調用__getattr__
。 簡單的解決方案是將Document
和Filename
添加到類中,以便找到它。
class ApplicationSettings(object):
Document = None
Filename = None
RootXml = '<?xml version="1.0"?><Settings></Settings>'
...
你真正需要的是一個描述符 。 像這樣掛鈎__getattr__
和__setattr__
並不是真正推薦的方法。
我會使用屬性 。 使用@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
然后,您可以訪問Cx
,它將自動調用x的getter,並在分配給Cx
時自動調用x的setter。
顯然,如果我在__setattr__
檢查屬性名稱, __setattr__
我可以調用object的__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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.