2012-02-21 7 views
3

[OK]をので、私はそれがアイテムのリンクにアクセスしようとしたときを除いて素晴らしい作品、データを介してデータにアクセスする際に使用するため__getitem__機能を持っている私自身の変数のハンドラ[キー]を構築しました:Python - 辞書 - __getitem__を修正しますか?

data["key"]["subkey"] 


def __getitem__(self, key, **args): 
    print key 
    ... 
    return self.dict[key] 

存在しないサブキーにアクセスしようとすると、Pythonは "サブキー"を印刷せずにKeyErrorを返すだけですが、これはなぜですか、そして私が実際に得ようとしているものを印刷するにはどうしたらよいですか?

私はおそらくメカニックを誤解していると知っていますが、辞書をエミュレートし、要求されているデータ列に従う方法がありますか?主に私は動的辞書フローの不足している変数を記録することができ ...

明らかにこれは動作します(しかし、それは私が好きなネイティブ構文ではありません):

data["key:subkey"] 

def __getitem__(self, key, **args): 
    for slice in key.split(':'): 
     print key 
    ... 

目的は以下をエミュレートすることです、

作品:

data = {'key' : {'subkey' : 1}} 
print data["key"]["subkey"] 

は動作しませんが、私は__getitem__内の例外をキャッチして、マイルを作成したいです

data = {'key' : {}} 
print data["key"]["subkey"] 

ソリューション:

class Var(): 
    def __init__(self): 
     self.dict = {'test' : {}} 
    def __getitem__(self, var, **args): 
     print ':',var 
     if var in self.dict: 
      v = Var(self.dict[var]) 
      return v 

print vHandle['test']['down'] 

出力:

:テスト

ダウンssingキーは自動的に、または単に不足しているサブキーを記録します

なし

+0

私はここに何かを見逃しているのですか?またはこれは全くdownvoteに値しませんでしたか? downvoterは自分自身を説明できますか? – Polynomial

+0

'データ 'の種類は何ですか? 'data [" key "]'の型は何ですか?おそらくもっとコードを表示する必要があります。そうでなければ、私たちができることは推測です。 (私のdownvoteではありません) –

+2

いいえ、あなたはそれを直接行うことはできません(あなたは同じ細かい処理をしたラップされたオブジェクトを返すことができます)。このように考えると、 '_ = data ['key']'の後に '_ ['subkey']'が続きます。代わりに 'data ['key'、 'subkey']'(タプルキー)がデータにアクセスするための有効な方法であればそれを使うことができます。 –

答えて

5

実際には、Pythonがdata["key"]["subkey"]などの式に遭遇したとき、内部的に行われるものは(data["key"])["subkey"]です。つまり、式の最初の部分が解決されます。オブジェクト「データ」から項目「キー」を検索することです。次に、Pythonはその式の結果のオブジェクトに対して__getitem__を呼び出します。 そのような結果のオブジェクトに__getitem__メソッド自体がない場合、エラーが発生します。

が2つの回避策があります:あなたはどちらかのはず「タプルインデックス」と作品 - (あなたがキーとしてタプルインスタンスを持って天気をあなたの__getitem__方法にして、テスト) data["key", "subkey"]などが - や特殊なオブジェクトを返します__getitem__作ります__getitem__メソッドもあります。要求されたキーを記録することだけであっても。

+0

これはどのように動作するのですか?私はちょうどpythonが自動的に同じ変数インスタンスを介して__getitem__を最初のキーの後に呼び出すと仮定しました。私は変数ハンドルの2番目のインスタンスを返さなければならないと思いますので__getitem__が2番目の呼び出し。 ありがとうございます! – Torxed

4

は覚えていません:tmp = foo['bar']['baz']は、だからあなたの__getitem__方法はまた、__getitem__方法を含む新しいオブジェクトを返す必要があり、任意の深さを可能にしtmp = foo['bar']; tmp = tmp['baz']

と同じです。

+0

私は、変数ハンドラの2番目のインスタンスを "変数ハンドラ"から返さなければならないと思いますので、__getitem__も2番目の呼び出しにも存在します。 ありがとうございます! – Torxed