2013-07-22 2 views
1

나는 회원들을 점검하고 목록을 만들 수있는 수업을 갖고있다. 그러나, 나는이 클래스를 자식 클래스에 반환하기를 원하기 때문에이 클래스를 하위 클래스로 만들 것이다. (C++에서는 추상 클래스이다.)Python에서 부모로부터 __dict__ 자식에 액세스 하시겠습니까?

파이썬에서는 이것이 가능한가, 아니면 좋은 생각일까요? 그리고 후속 조치는 inspect 모듈없이 가능합니까? 그래서 같이

:

class A: 
    @staticmethod 
    def GetMembers(): 
     return dict(vars(A)) 

class B(A): 
    FOO = 'foobar' 
    BAR = 'barfoo' 

그러나, 테스트 계시 :

>>> A.GetMembers() 
{'__module__': '__main__', '__doc__': None, 'GetMembers': <staticmethod object at 0x02219BB0>} 
>>> B.GetMembers() 
{'__module__': '__main__', '__doc__': None, 'GetMembers': <staticmethod object at 0x02219BB0>} 
>>> dict(vars(B)) 
{'__module__': '__main__', 'FOO': 'foobar', 'BAR': 'barfoo', '__doc__': None} 

내가 FOOdict(vars(B)) 같은 BAR 않습니다를 포함 B.GetMembers()를 원한다.

+0

사용 ['@의 classmethod'] (http://docs.python.org/2/library/functions.html#classmethod) 대신'@ staticmethod'를 사용하고'cls' 매개 변수를 검사하십시오. 당신의 제약 조건은 "inspect"모듈을 사용하지 않고 "전혀 이해가되지 않습니다. 그것은 객체를"반사 "로 검사하는 것이 모듈입니다. 왜 그것을 사용하지 않겠습니까? 마지막으로, 코드 샘플'FOO'와'BAR'는 클래스 객체'B'의 멤버입니다. ** B 인스턴스의 ** 멤버가 아닙니다. 인스턴스 자체에 영감을주지 않고 클래스 인스턴스의 속성을 열거 할 수있는 일반적인 방법은 없습니다. – millimoose

+0

[slot] (http://docs.python.org/2/reference/datamodel.html#slots), [named tuples] (http : // docs)와 같은 특정 패턴을 사용하여 마지막으로 사용할 수있는 방법이 있습니다. .python.org/2/library/collections.html # collections.namedtuple) 또는 [traits] (http://code.enthought.com/projects/traits/) 또는 다른 어떤 방법으로 명시 적으로 메타 데이터를 클래스에 추가하십시오. 일반적으로 어떤 물건에 대해서도 아닙니다. – millimoose

+0

@staticmethod는 끔찍합니다 ... 나는 그것을 사용하는 어떤 이유도 보지 못했습니다 ... –

답변

5

@staticmethods는 클래스 나 클래스 범위에 대한 인식이 없으므로 정적 메서드가 하위 클래스에서 호출되었음을 알 수있는 방법이 없습니다.

@classmethods는 첫 번째 인수로 자신의 클래스 유형을 수신합니다 (마치 instancemethods가 첫 번째 인수로 self를 얻는 것처럼). 그러면 cl의 모든 것을 호출 할 수 있습니다. 테스트

>>> A.GetMembers() 
{'__module__': '__main__', '__doc__': None, 'GetMembers': <classmethod object at 
0x0286D130>} 
>>> B.GetMembers() 
{'__module__': '__main__', 'FOO': 'foobar', 'BAR': 'barfoo', '__doc__': None} 
>>> 

class A: 
    @classmethod 
    def GetMembers(cls): 
     return dict(vars(cls)) 

class B(A): 
    FOO = 'foobar' 
    BAR = 'barfoo' 

는 다른 방법으로 당신은 또한 상위 클래스 dicts에 액세스 할 수 있습니다. 클래스 (또는 인스턴스) 메소드에서 당신은을 통해 BASECLASSES에 액세스 할 수 있습니다 cls.__bases__

class A: 
    @classmethod 
    def GetMembers(cls): 
     d = dict() 
     for basecls in cls.__bases__: 
     if hasattr(basecls,"GetMembers"): 
      d.update(basecls.GetMembers()) #call inherited GetMembers 
     else: 
      d.update(dict(vars(basecls))) #no GetMembers inherited from basecls so just get its vars 
     d.update(dict(vars(cls))) 
     return d 

>>> class B(A): 
...  FOO = 'foobar' 
...  BAR = 'barfoo' 
... 
>>> class C(A): 
...  FOOBAR = "whatever" 
... 
>>> class X(B,A): 
...  FOO = 'foobar2' 
...  COLOR = 'red' 
... 
>>> class X(B,C): 
...  FOO = 'foobar2' 
...  COLOR = 'red' 
... 
>>> X.GetMembers() 
{'__module__': '__main__', 'BAR': 'barfoo', 'COLOR': 'red', 'FOOBAR': 'whatever' 
, 'FOO': 'foobar2', '__doc__': None} 
+0

완벽, 고마워! – Nate

+0

좋은, 우리가 학습자를 위해 계속하고있는 것을 설명하는 것이 신경을 쓴다?, 어떻게해서든지 upvote – Stephan

+0

나는 조금 더 설명했다 –

관련 문제