4

私はPythonにかなり慣れていません。__get最近、多くの PHP をプログラミングする中で、__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)
4

4 に答える 4

1

__getattr__Python がインスタンス自体またはその基本クラスのいずれかで属性を見つけることができない場合にのみ呼び出されます。Document簡単な解決策は、 andFilenameをクラスに追加して、検出されるようにすることです。

class ApplicationSettings(object):
    Document = None
    Filename = None
    RootXml = '<?xml version="1.0"?><Settings></Settings>'
    ...
于 2011-08-19T00:47:41.117 に答える
0

プロパティを使用します。デコレータを使用@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のゲッターが自動的に呼び出され、に割り当てるとxのセッターが自動的に呼び出されますC.x

于 2011-08-19T16:09:30.123 に答える
0

ここで本当に必要なのは記述子です。フッキング__getattr__など__setattr__はあまりお勧めできない方法です。

于 2011-08-19T01:37:18.053 に答える
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)
于 2011-11-26T00:15:09.070 に答える