簡體   English   中英

Python - 如何定義不受__getattr__影響的屬性?

[英]Python - How to define attributes not affected by __getattr__?

我對Python很新。 在最近編程很多PHP時,我習慣了一些創造性地使用__get__set “魔術”方法。 這些只在該類的公共變量不存在時才被調用。

我試圖在Python中復制相同的行為,但似乎失敗了。 鑒於似乎沒有辦法以C ++ / PHP方式實際定義類變量,當我嘗試在我的類中通常使用變量時(即通過self),它最終調用__getattr__

如何定義我不希望受__getattr__影響的類的屬性?

我正在嘗試做的一些示例代碼如下,我想要self.Documentself.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__ 簡單的解決方案是將DocumentFilename添加到類中,以便找到它。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM