0

記述子を内部に格納する辞書のようなオブジェクトがあります。

 class MyDict(object):
    def __init__(self):
        dict.__init__(self)

    def __getitem__(self, key):
        v = dict.__getitem__(self, key)
        if hasattr(v, '__get__'):
           return v.__get__(None, self)
        return v

class MyDescriptor(object):
    def __init__(self, value, attrib={}):
        self.__value = value
        self.attrib= attrib

    def __get__(self, instance, owner):
        return self.__value

    def __set__(self, instance, value):
        self.__value = value

私は次のことができるようになりたいです:

d = MyDict()
d['1'] = MyDescriptor("123", {"name": "val"})
print d['1']                     # prints "123"
print d['1'].attrib["name"]      # prints "val"

私のクラスは機能しません。手伝っていただけませんか?

4

2 に答える 2

1

示されているものが他にない限り、問題を解決するためのソリューションは不必要に複雑に見えます。なぜこれを単純に行わないのですか?

class MyObject(object):
    def __init__(value, attrib=None):
        self.__value = value
        self.attrib = {} if attrib is None else attrib

    def __str__(self):
        return __value

d = {}
d['1'] = MyObject("123", {"name": "val"})
print d['1']                     # prints "123"
print d['1'].attrib["name"]      # prints "val"

コードが機能しない理由については、いくつかの明らかな問題があります。

  • のさまざまな特別なメソッドでの呼び出しから、はサブクラス化することを意図して__dict__いるように見えるので、定義は次のようになります。MyDictdict

    class MyDict(dict):
        ...
    
  • 正しくありませんがsuper、基本クラスを直接参照するよりも使用することをお勧めします。そのため、dict.__init__(self)になりsuper(MyDict, self).__init__()、にdict.__getitem__(self, key)なりsuper(MyDict, dict).__getitem__(key)ます。

  • 敷居を取得するための呼び出しが機能しますが、メソッドの仕様と一致しません。あなたはそれをと呼ぶべきv.__get__(self, MyDict)です。ただし、実際の使い方は__get__冗長であり、この使い方が主な問題点だと思います。

  • クラスMyDescriptorでは、早期バインディングにより、の予期しない結果が得られますattrib。それを宣言するためのより良い方法については、上記の私の例を参照してください。

説明の代わりに、実際に必要なのは、文字列のように見える(「のように見える」の定義の場合)が、属性を持つオブジェクトであると思われますattrib。これを行うために、まったく別のユースケースを対象とした記述子を作成する必要はありません。上記の私の例は、文字列に「似ている」オブジェクトの要件を満たすクラスを示しています。「似ている」とは、文字列を出力することを意味しますが、次のようなものが必要です。

class MyString(str):
    def __init__(self, value, attrib=None):
        super(MyString, self).__init__(value)
        self.attrib = {} if attrib is None else attrib
于 2012-12-05T15:29:21.870 に答える
1

これがあなたのユースケースを解決するかどうかはわかりませんが、あなたが述べた結果を達成するという点では、単にMyDictクラスを削除して通常のを使用することができますdict:

d = {}

次に、返されるクラスに__str__メソッドを追加すると、説明した結果が得られます。MyDescriptorself.__value

>>> d['1'] = MyDescriptor("123", {"name": "val"})
>>> d['1']                     
123
>>> d['1'].attrib["name"] 
val
于 2012-12-05T15:02:39.107 に答える