2017-10-08 9 views
4

파이썬에서 dict과 같은 클래스를 만들려고합니다.클래스의 dict() 덮어 쓰기

클래스를 만들 때 Python에 내장 클래스를 만드는 방법을 알려주는 특정 메서드가 있습니다. 예를 들어, __int__ 메서드를 재정의하면 사용자가 클래스 인스턴스에서 int()을 사용하면 반환 할 대상을 Python에 알려줍니다. __float__와 동일합니다. __iter__ 메소드를 재정 의하여 파이썬이 클래스의 반복 가능한 객체를 만드는 방법을 제어 할 수도 있습니다 (파이썬이 클래스의 listtuple을 만드는 데 도움이 될 수 있음). 내 질문은 파이썬에게 사용자 정의 클래스의 dict을 만드는 방법을 어떻게 말할 것인가? 특별한 __dict__ 방법이 없으므로 어떻게 할 것입니까? 나는 다음과 같이합니다 : 나는 dict에서 클래스 상속을 시도했습니다

class Foo(): 
    def __dict__(self): 
     return { 
      'this': 'is', 
      'a': 'dict' 
     } 

foo = Foo() 
dict(foo) # would return {'this': 'is', 'a': 'dict'} 

,하지만 그렇게 dict ISN에서 상속 때문에 dicttype에서 상속하려고 서브 클래스의 나중에 코드에서 오류가 발생합니다 가능성이 없다. 그것을 할 다른 방법이 있습니까? (당신이 dictiter()를 사용할 때 반환됩니다 무엇을) dict_keyiterator 개체를 반환 할 수 있도록

또한, 나는 이미 __iter__ 방법을 무시했지만, 여전히 어떻게해야 작동하지 않습니다. 당신이 튜플의 반복자를 반환하기 위해 __iter__를 설계, 그래서 만약

+0

당신이 collections.abc'에서 상속 해봤 * Mapping' 아직? –

+0

'collections.abc.Mapping'은'ABCMeta' 클래스입니다. 제 코드는 이미'type' 메타 클래스 위에 구축되었으므로 많은 코드가'ABCMeta '와 호환되지 않습니다. 나는 모든 코드를 'ABCMeta'로 작업하려고 변경하려고했지만 '매핑'과 같은 추상 클래스에 의존하지 않는 더 쉬운 방법이 있기를 바랐다. – ChristianFigueroa

+0

'to_dict'와 같은 이름의 클래스에'@ staticmethod'를 추가하면됩니다.이 클래스를 명시 적으로 호출하여 사전을 만들 수 있습니다. 즉'result = foo_obj.to_dict()'를 호출합니다. – martineau

답변

2

dict가 쌍의 반복 가능한 호출 할 수 있습니다, 귀하의 예를 들어 당신이 원하는만큼 작동합니다

class Foo: 
    def __iter__(self): 
     yield from { 
      'this': 'is', 
      'a': 'dict' 
     }.items() 

dict(Foo()) 
{'a': 'dict', 'this': 'is'} 

당신이 원하는 경우 클래스가 파이썬 사전처럼 행동한다면 인스턴스를 반복하면서 키를 반복하므로 abc.Mapping으로 정의 된 인터페이스를 구현할 수 있습니다.

당신은, __getitem__, __iter____len__을 구현하고, abc.Mapping에서 상속 또는 __getitem__, __iter__의 모든 __len____contains__, keys, items, values, get, __eq____ne__을 구현하여이 작업을 수행 할 수 있습니다.

+1

'Foo' 객체에'dict'을 만들기 위해 올바르게 작동하지만 아이템의 키를 반복 할 수는 없습니다. 'for i for Foo()'와 같은 것은 객체의 _keys_를 반복하지 않고 _tuple_ (key, value) 개의 튜플을 반복합니다. – ChristianFigueroa

+1

@Christian : 좋은 지적 ... 그러나'Foo' 클래스는'dict'의 정식 하위 클래스가 아니므로 반복 될 때 정확하게 동작 할 것이라고 가정하면 완전히 합리적이지 않습니다. – martineau

+0

ForeverWintr : 클래스 (단지)에'__getitem __()'메쏘드를주는 FWIW는 내장 된'dict' 클래스 객체가 그것들의 인스턴스로부터 생성 될 수있게합니다. 나는 아직도 다른 클래스의 다소 애매한 구성 인자 세부 사항에 의존하지 않고 더 명시 적으로 클래스에'to_dict()'메소드를 제공하는 것이 더 좋을 것이라고 생각합니다. – martineau

1

@ForeverWintr의 answer에있는 접근 방식은 상당히 똑똑하고 작동하지만, dict 클래스 생성자에 전달 된 인수의 속성에 대한 아주 구체적인 세부 정보를 활용하기 때문에 조금 애매합니다.

그런 이유로 더 나은 접근 방식은 원하는 것을 수행하는 방법을 추가하는 것에 대한 내 의견에서 말했던 것일뿐입니다 (정확히 무엇이 진행되고 있는지를 나타내는 이름을 단순히 어떻게 표시하는지 보여줍니다).

예제 코드 :.

class Foo: 
    def to_dict(self): 
     return {'this': 'is', 'more': 'clear'} 

print(Foo().to_dict()) # -> {'this': 'is', 'more': 'clear'}