質問
私は、以下のPython2.6プログラムYAMLの定義を使用 PyYAML):
import yaml
x = yaml.load(
"""
product:
name : 'Product X'
sku : 123
features :
- size : '10x30cm'
weight : '10kg'
"""
)
print type(x)
print x
その結果、以下の出力:
<type 'dict'>
{'product': {'sku': 123, 'name': 'Product X', 'features': [{'weight': '10kg', 'size': '10x30cm'}]}}
を作成することができるオブジェクトの分野から x
?
いて以下の
print x.features[0].size
それを作成することができ、インスタンスから、既存のクラスがないためにこの特定のシナリオ。
編集:
- 更新の混乱につきましては当社は一'強く型付けされたオブジェクト'.
- 変更へのアクセス
features
をindexer示唆されるようにアレックスMartelli
解決
あなたは辞書のインデックスの代わりに属性へのアクセスを使用して、「で呼び出すことができますインスタンスにそれをラップしたいのですが「リストのインデックスの代わりに - わからない 『インデックス強く型付けされたが、』確かに、それはだ、これに関係している、またはあなたが.features(0)
が.features[0]
よりも優れていると思う理由が、(リストのインデックスに、このような、より自然な方法!)実現可能。例えば、単純なアプローチは次のようになります。
def wrap(datum):
# don't wrap strings
if isinstance(datum, basestring):
return datum
# don't wrap numbers, either
try: return datum + 0
except TypeError: pass
return Fourie(datum)
class Fourie(object):
def __init__(self, data):
self._data = data
def __getattr__(self, n):
return wrap(self._data[n])
def __call__(self, n):
return wrap(self._data[n])
x = wrap(x['product'])
は、あなたの全体的なロジックが明らかにx.product.features(0).size
を必要とするときに、そのレベルをスキップしたい理由を、私はわかりませんが、明らかにスキップのが良いにハードコードされたのではなく、呼び出しの時点で適用されることを(あなたの願いを与える必要がありますのでラッパークラスまたは私はちょうど示されてきたラッパーファクトリ関数)。
編集:OPは、彼が
に最後の2行を変更するだけで、むしろfeatures[0]
よりfeatures(0)
たいん言うように
def __getitem__(self, n):
return wrap(self._data[n])
すなわち、代わり__getitem__
の__call__
を(マジックメソッドは索引付けの基礎となる)(マジックメソッドがインスタンス・コールの根底にある)を定義する。
(ここでは、Fourie
)「既存のクラス」に代わるものは、ラップのdictを内省に基づいてその場で新しいクラスを作成することです - 実際にをされていない場合、実行可能な、あまりにも、真剣に濃い灰色黒の、魔法、と私は考えることができる任意の実際の作用効果なしています。
、彼はなど、そのように取得される可能性があります信じている利点、私はそれを行う方法を紹介します(とおそらく、私はまた、なぜ切望-のための のない事実であるだろう利点;-)見せします。しかし、時には、上記作品のようなプレーンな、簡単なコードだけで罰金シンプルさは、任意のプログラミング努力で重要な品質で、かつ「濃いマジック」を使用して、一般的なアイデアの最善ではありません - !)