문제

다음 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가 제안한대로 인덱서에
도움이 되었습니까?

해결책

따라서 숫자, 중첩 사전, 목록이 될 수있는 문자열 키와 값이있는 사전이 있으며, Dict Indexing 대신 속성 액세스를 사용할 수있는 인스턴스로 랩핑하고 "색인으로 호출하십시오". 목록 인덱싱 대신 - "강력하게 입력 한"가 무엇인지 확실하지 않음 .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가 말한 것처럼 그가 원한다고 말합니다 features[0] 보다는 features(0), 마지막 두 줄을 변경하십시오

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

즉, 정의하십시오 __getitem__ 대신 (인덱싱의 기본 마법 방법) __call__ (인스턴스 통화의 기본 마법 방법).

"기존 클래스"에 대한 대안 (여기, Fourie) 랩핑 된 덕트를 내성적으로 지정하는 데 기초하여 즉시 새로운 클래스를 만드는 것입니다. 검은색, 마법, 그리고 내가 생각할 수있는 실제 운영 이점이 없습니다.

OP가 메타 프로그래밍 피크가 즉석에서 수업을 만들 수있는 절정에 이르렀을 때 왜 자신이 왜 그렇게 할 수 있는지, 그가 어떤 이점을 얻을 수 있다고 믿는 지 등을 정확히 명확히 할 수 있다면, 나는 어떻게 해야할지 보여줄 것입니다 (아마도 아마도, 아마도, 아마도, 아마도 나는 또한 갈망하는 이점이 왜 이점이 될지 보여줄 것입니다 ~ 아니다 실제로 거기에있다 ;-). 그러나 단순성은 모든 프로그래밍 노력에서 중요한 품질이며, 위와 같이 평범하고 간단한 코드가 잘 작동 할 때 "딥 어두운 마법"을 사용하면 일반적으로 최고의 아이디어가 아닙니다!-)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top