2011-12-27 2 views
4

기본 클래스에서 상속 된 클래스 수준 사전을 업데이트하는 깨끗하고 간단한 방법을 찾고 있습니다. 그래서Python 업데이트 상속 된 클래스 수준 사전

class Foo(object): 
    adict = {'a' : 1} 

class Bar(Foo): 
    adict.update({'b' : 2}) # this errors out since it can't find adict 

: 예를 들어

Foo.adict == {'a' : 1} 
Bar.adict == {'a' : 1, 'b' : 2} 

여기 인스턴스를 사용하지 선호하고, 가능하면 두 클래스 메소드를 사용하지 것입니다.

답변

3

그래도 문제가 없더라도 새 사전을 만드는 대신 사전을 업데이트하면됩니다 (예 : Foo.adict is Bar.adict이므로 Foo.adict == Bar.adict). 어떤 경우

는, 가장 간단한 방법은 명시 적으로 부모 클래스의 딕셔너리를 참조하는 것입니다 (그것을 복사, 위 참조) :

class Bar(Foo): 
    adict = dict(Foo.adict) 
    adict.update({'b': 2}) 
+0

감사합니다 -이 확실히 작동 - 외에 명시 적으로 상위 클래스를 참조 포함하지 않았다 내가 (예를 들면 슈퍼 같은) 좀 더 일반적인 뭔가 알아낼 수 있다고 기대했다 계승. – gnr

+0

클래스 사전을 사용하기 때문에 실제로 여기에서는 상속을 많이 사용하지 않습니다. 대신에 그냥 글로벌 dict 수 있습니다. 같은 효과. –

0

"나는 여기에 인스턴스를 사용하지 선호하고, 가능하면 것 클래스 메소드도 사용하지 마십시오. "

오른쪽. 그러지 마라.

foo_adict = {'a' : 1} 

def B(): 
    foo_adict.update({'b': 2}) 

난 당신이 클래스 속성 레벨 사전을 사용하는 이유, 그것은 거의 유용하거나 예상되는 방식으로 동작하지 모르겠어요.

+0

반원 * *이 * 그들의 용도가 * 있습니다. 사실, 고급 기능이지만 전역 변수만큼 나쁘지는 않으며 그에 상응하지 않습니다. 클래스 당 별도의 값을 가질 수 있습니다 (코드 스 니펫과 동일). 지금 작업하고있는 코드 기반은 클래스 멤버를 몇 군데에서 사용합니다.하지만 무겁게 메타 프로그래밍을하는 경우에는 그렇습니다. 논리적 그룹화를 더욱 명확하게하는 것 외에도,'classmethod'는 자신이 작업하는 데이터를 * 어딘가에서 가져와야합니다 *. – delnan

+0

반원이 자신의 용도로 사용합니다. 클래스 멤버 * 사전 (또는 다른 mutables)은 일반적으로 사용하지 않습니다. –

+0

약간의 컨텍스트를 제공하기 위해 API를 작성하기 위해이 조직 방법을 사용하고 있습니다. 예를 들어, 나는 Foo.adict [ 'a']와 Bar.adict [ 'a']가 다른 값으로 초기화 될 수 있도록하고 싶지만, 대부분의 변수는 같을 것이다. 클래스 정의 이후에 사전은 수정되지 않습니다. 또한 Foo와 Bar는 상속되지 않는 정적 속성을 필요로합니다. 나는 왜 클래스 멤버 사전을 사용하는 것이 본질적으로 나쁜 생각인지 모르겠다. – gnr

0

이 문제도 만났습니다. Foo 클래스

import six 


class CheckerMeta(type): 

    def __new__(cls, name, bases, attrs): 
     new_class = super(CheckerMeta, cls).__new__(cls, name, bases, attrs) 

     base_configs = [bc.config for bc in bases if hasattr(bc, 'config')] 
     configs = base_configs + [new_class.config] 

     new_class.config = {} 
     for config in configs: 
      new_class.config.update(config) 

     return new_class 


class BaseChecker(six.with_metaclass(CheckerMeta)): 
    config = {} 


class CheckerA(BaseChecker): 
    config = {'a': 1} 


class CheckerB(BaseChecker): 
    config = {'b': 2} 


class CheckerC(CheckerA, CheckerB): 
    config = {'c': 3} 


assert CheckerA.config == {'a': 1} 
assert CheckerB.config == {'b': 2} 
assert CheckerC.config == {'a': 1, 'b': 2, 'c':3} 
0

초기화 adictBarsuper 다음 updateinit를 호출하여 초기화 : 나는 또한 다중 상속에서 작동 할 수있는 메타 클래스를 사용하여 그것을 해결.

class Foo(object): 
    def __init__(self): 
     self.adict = {'a': 1} 


class Bar(Foo): 
    def __init__(self): 
     super(Bar, self).__init__() 
     self.adict.update({'b': 2}) 

예 :

In [14]: b = Bar() 
In [15]: b.adict 
Out[15]: {'a': 1, 'b': 2}