2017-11-27 5 views
-2

は、私は、親クラスの代わりにクラスメソッドでsuper()を使用することができなければならない:configparserコンストラクタでsuper()を使用できないのはなぜですか? Pythonの3で

class demodict(OrderedDict): 

    def __setitem__(self, key, val): 
     print(key) 
     super().__setitem__(self, key, val) 

上記挙動Iはdemodict()をインスタンス化し、それに値を追加するとき、期待どおり。しかし、私はConfigParserオブジェクトのデータ型としてそれを使用する場合、何かがうまくいかない:

>>> Config = configparser.ConfigParser(dict_type=demodict) 
Traceback (most recent call last): 
    File "<pyshell#15>", line 1, in <module> 
    conf = configparser.ConfigParser(dict_type=demodict) 
    File ".../anaconda/lib/python3.4/configparser.py", line 588, in __init__ 
    self._proxies[default_section] = SectionProxy(self, default_section) 
    File "<pyshell#14>", line 5, in __setitem__ 
    super().__setitem__(self, key, val) 
    File ".../anaconda/lib/python3.4/collections/__init__.py", line 67, in __setitem__ 
    if key not in self: 
TypeError: unhashable type: 'demodict' 

私は、親クラスとして平野dictOrderedDictを交換した場合、エラーも奇妙取得:

Traceback (most recent call last): 
    File "<pyshell#9>", line 1, in <module> 
    conf = configparser.ConfigParser(dict_type=demodict) 
    File ".../anaconda/lib/python3.4/configparser.py", line 588, in __init__ 
    self._proxies[default_section] = SectionProxy(self, default_section) 
    File "<pyshell#7>", line 6, in __setitem__ 
    super().__setitem__(self, key, val) 
TypeError: expected 2 arguments, got 3 

super()の代わりにOrderedDictまたはdictを明示的に書き込む場合は、dict_typeとしてdemodictを問題なく使用できます。誰かが何が起こっているか説明できますか? (簡単な回避策があるので、解決策よりも原因についてもっと興味があります...)

+3

'super().__ setitem__は自動的に第1引数として' self'を渡します。 'super().__ setitem __(key、val)'を実行するだけで動作します。 – vaultah

+0

確かに!それが問題を解決しました。ダーだけでなく、どのように奇妙。私は 'super()'のドキュメントをもっと慎重に読んでいたはずです。あなたは解説として解答としてそれを書いてもらえますか? – alexis

+0

私はポイントを惜しみませんが、なぜ誰かがこれが悪い質問であると思うのは不思議です。 – alexis

答えて

1

通常のメソッドバインディングのように、super()プロキシオブジェクトのメソッド属性アクセスは、暗黙的にオブジェクトを渡します。最初の位置引数。

変更この:これに

super().__setitem__(self, key, val) 

は:

super().__setitem__(key, val) 

OrderedDict doesn't use cooperative inheritanceこと、すなわち、それだけで直接dict.__setitem__を呼び出します。理想的には、継承チェーンのすべてのオブジェクトはsuperを使用する必要があります。 OrderedDictを複数継承構造に使用する場合は、慎重に進めてください。

+2

"vaultahのコメントによれば、それは渡された自己ではありませんが、プロキシオブジェクトは"あなたは何を話していますか? – user2357112

+0

'self'は' demodict'インスタンスになり、 'super()'は 'super'インスタンスになります。 – wim

+2

'super()'は 'super'インスタンスですが、' super() 'オブジェクトはスーパークラス' __setitem__'メソッドに 'self'として渡されるものではありません。 – user2357112

関連する問題