5

次の Python 2.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ました Alex Martelli
4

1 に答える 1

8

したがって、数値、ネストされた辞書、リストである文字列キーと値を持つ辞書があり、それをインスタンスにラップして、dict インデックスの代わりに属性アクセスを使用し、「インデックスを使用して呼び出す」ことができます。リストのインデックス付けの代わりに - 「強く型付けされた」ことがこれと何の関係があるのか​​ 、または(リストにインデックスを付けるためのより自然な方法!).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わかりませんが、ラッパークラスまたはラッパーでハードコーディングするよりも、呼び出し時点でスキップを適用する方が適切であることは明らかです)先ほど示したファクトリ関数)。

編集features[0]: OPが言うようにfeatures(0)、最後の2行を次のように変更するだけです

  def __getitem__(self, n):
    return wrap(self._data[n])

つまり、 (インスタンス呼び出しの基礎となる魔法のメソッド__getitem__) の代わりに (索引付けの基礎となる魔法のメソッド) を定義します。__call__

「既存のクラス」(ここではFourie)に代わるものは、ラップされた dict の内省に基づいてオンザフライで新しいクラスを作成することです-これも実行可能ですが、実際にはではないにしても、真剣に暗い灰色であり、魔法であり、何もありません私が考えることができる実際の運用上の利点。

OPが、その場でクラスを作成するメタプログラミングのピークの後に彼が切望している理由、彼がそのようにして得ていると信じている利点などを正確に明確にすることができれば、私はそれを行う方法を示します(そして、おそらく、また、切望されたアドバンテージが実際には存在しない理由も示します;-)。しかし、単純さはどのようなプログラミング作業においても重要な性質であり、上記のようなプレーンで単純なコードが問題なく機能する場合に「深い闇の魔法」を使用することは、一般的に最善のアイデアではありません!-)

于 2010-03-14T17:17:13.450 に答える