2013-12-18 2 views
3

특정 유형의 클래스 속성에 연결된 클래스에 대한 역 참조를 제공하는 신뢰할 수 있고 무난한 방법을 찾고 있습니다.객체 속성을 클래스 또는 객체에 연결하는 모범 사례

즉, 아래에 정의 된 클래스 정의가있는 경우 SomeAttribute()SomeClass 유형의 객체에 대한 참조를 제공하고 싶습니다.

class SomeClass(object): 
    attribute = SomeAttribute() 

현재 이런 종류의 속성을 가진 클래스를 생성 한 후 수동 메소드 호출에 의존하는 구현이 있습니다. (아래 예 참조). 현재 접근법의 문제점은 많은 코드가 참조 클래스가 액세스 될 때마다 속성에 이미 채워져 있는지 확인해야한다는 것입니다.

코드가 bind_attributes 인 경우 코드가 __init__ 메서드에 배치 될 수있는 경우 클래스를 초기화해야한다고 요구할 수 있습니다. 그러나 인스턴스가 필요하지 않은 경우에도 클래스를 인스턴스화해야합니다. 나는 더 나은 솔루션이 메타 클래스를 사용하여 구현 될 수 있다고 확신하지만, 메타 클래스를 사용하는 pythonic 구현이 어떻게 보일지 모르겠습니다.

import inspect 

class Attribute(object): 
    def __init__(self, *params): 
     self._params = params 
     self._definition_class = None 

    def bind(self, definition_class): 
     self._definition_class = definition_class 

    def __call__(self): 
     return self._definition_class.separator.join(self._params) 


class Definition(object): 
    separator = ', ' 

    publications = Attribute('Books', 'Magazines') 
    clothes = Attribute('Shoes', 'Gloves', 'Hats') 

    @classmethod 
    def bind_attributes(cls): 
     for name, attribute in inspect.getmembers(cls, lambda m: isinstance(m, Attribute)): 
      attribute.bind(cls) 


>>> Definition.bind_attributes() 
>>> Definition.publications() 
'Books, Magazines' 
>>> Definition.clothes() 
'Shoes, Gloves, Hats' 

답변

1

메타 클래스로이 작업을 수행 할 수 있습니다. 예를 들면 :

class MyMeta(type): 
    def __new__(mcls, name, bases, members): 
     cls = type.__new__(mcls, name, bases, members) 
     for m in members.values(): 
      if isinstance(m, SomeAttribute): 
       m.bound_cls = cls 
     return cls 

지금은 물론 하나의 단점이 기능은 메타 클래스를 사용하는 당신이 기능이 필요한 때문에 모든 클래스, 클래스가 아닌 속성에 연결되어 있습니다 :

class SomeClass(object): 
    __metaclass__ = MyMeta 

    attribute = SomeAttribute() 
+0

어떤 경우를 나는 수업에서 상속 받았다. '클래스 OtherClass (SomeClass) : second_attribute = SomeAttribute()'. 상속 된 클래스에'__metaclass__'를 설정해야합니까? – lyschoening

+0

하위 클래스와 잘 작동합니다. 그들은 자동으로 기본 클래스의 메타 클래스를 상속받습니다. 한 가지주의해야 할 점은 기본 클래스에 정의 된 특성은 여전히 ​​기본 클래스에 바인딩된다는 것입니다. 서브 클래스가 동일한 속성을 가지지 만 서브 클래스에 구체적으로 바인딩되게하려면 서브 클래스에서이 속성을 명시 적으로 재정의하거나 메타 클래스에서 조금 더 까다로운 작업을 수행하여 각 서브 클래스에 속성 사본을 작성해야합니다. 그렇게 할 수도 있지만 필요한지 확실하지 않습니다. – Iguananaut

+0

하위 클래스에 속한 속성이 선언 된 클래스에 바인딩되어있는 한 그것은 저에게 효과적입니다. 지금까지 내가 볼 수있는 것처럼 보입니다. 감사! (btw. 나는 당신의 예제에서'members.values ​​()'이어야한다고 생각한다) – lyschoening

관련 문제