2013-11-01 3 views
2

동적 클래스 변수를 만들려면 locals() 또는 __metaclass__을 사용하는 두 가지 옵션이있는 것 같습니다. 나는 locals()에 배정 팬이 아니지만 그것은 클래스 정의에서 작동하는 것 같고 그것보다 더 간결합니다 __metaclass__ 대안입니다.동적 클래스 변수 - locals() vs __metaclass__

이렇게하면 locals()을 사용할 수 있습니까? 두 가지 솔루션의 장점/단점은 무엇입니까?

meta_attrs = ["alpha", "beta", "gamma"] 

class C(object): 
    pass 

for attr in meta_attrs: 
    setattr(C, attr, attr.upper()) 

내가 다섯 번째 옵션 자신을 위해 갈 것이다 :

meta_attrs = ["alpha", "beta", "gamma"] 

def decorate(klass): 
    for attr in meta_attrs: 
     setattr(klass, attr, attr.upper()) 
    return klass 

@decorate 
class C(object): 
    pass 

여기에 네 번째 옵션이있다 :

kindall에서 언급 한 바와 같이
meta_attrs = ["alpha", "beta", "gamma"] 

class C(object): 
    local_context = locals() 
    for attr in meta_attrs: 
     local_context[attr] = attr.upper() 


class D(object): 
    class __metaclass__(type): 
     def __new__(mcs, name, bases, attrs): 
      for attr in meta_attrs: 
       attrs[attr] = attr.upper() 
      return type.__new__(mcs, name, bases, attrs) 


if __name__ == '__main__': 
    print C.alpha, C.beta, C.gamma 
    print D.alpha, D.beta, D.gamma 
+3

세 번째 옵션은 속성을 설정하는 클래스 데코레이터 또는 팩토리 함수입니다. – kindall

답변

1

__metaclass__는 호출 될 수 있습니다

class D(object): 
    def __metaclass__(name, bases, dct): 
     for attr in meta_attrs: 
      dct[attr] = attr.upper() 
     return type(name, bases, dct) 

이것은 locals() 방법만큼이나 간결하고, CPython의 구현 세부 사항에 의존하지 않습니다.

+0

나는 논리를 클래스에 유지하기 때문에이 것을 받아들입니다. 이것이 제가하려고했던 것입니다. 또한 새로운 것을 배웠습니다. 감사! – pyrospade

4

는 클래스 장식은 세 번째 옵션이 필요하지 않음 동적 클래스 속성 유스 케이스를 볼 수 없습니다. 필자가 정말로 필요하다면, 네 번째 옵션을 사용할 것입니다. 두 개 이상의 클래스에서 필요하지 않으면 데코레이터를 사용할 것입니다.

메타 크라스는 종종 지나치게 복잡하며, locals() 해킹은 실제로는 못 생기므로 피해야합니다.