2013-08-14 2 views
0

저는 최근에 OOP 탐색 킥을 탔습니다. 이벤트의 하나는 해당 이벤트의 일부 속성 세트를 계산하기 :다른 클래스에 대한 선택적 인수로 인스턴스 전달

나는 두 개의 클래스가 있습니다.

class Event(object): 
    def __init__(self,name,info): 
     self.name = name 
     self.category = info.category 
     self.classification = info.classification 

    @property 
    def attributes(self): 
     return dict((k,v) for k,v in self.__dict__.items()) 

class class1(object): 
    def __init__(self,some_number): 
     self.number = some_number 

    @property 
    def category(self): 
     #stuff 
     return category 

    @property 
    def classification(self): 
     #stuff 
     return classification 

지금은

e = Event('myevent', class1(42)) 
e.attributes 
{'category': 1, 
'classification': None, 
'name': 'myevent'} 

과 같은 작업을 수행 할 수 있습니다 그러나 나는 등 미래 class2의 수/조합, class3Event() 인스턴스를 제공하는 옵션을 갖고 싶어; 따라서 e.attributes이 적절한 모든 속성을 반환하도록 Event()init() 메소드가 정상적으로 처리되기를 원합니다. 압축을 풀기 위해 Event.__init__ 매개 변수를 주면 할당 할 필요가있는 속성 이름을 알 필요가 없습니다. 궁극적으로이 이벤트를 만들고이 패러다임을 사용하여 필요에 따라 다양한 속성 집합을 만들고 업데이트 할 수있게하려는 것입니다. 가능한가? 내 생각

+2

첫째, 왜 dict ((k, v) for k, v 자체에 .__ dict __. 항목())'그냥 dict를 복사하려면? 둘째, 어째서 왜 처음에 사전에 딕셔너리를 속이고있는 것입니까? 어쩌면 당신은 [당신의 부분적인 해결책을 보여주는 대신에 실제로 성취하려는 것을 더 잘 설명해야합니다] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – abarnert

+0

귀하의 질문을 이해하려고하지만 매우 명확하지 않습니다. 나는 당신이 그것을 더 잘 설명한다면 당신 자신이 대답을 내놓을 수있는 좋은 기회가 있다고 의심한다. –

+0

나는 내 머리를 숙 였기 때문에 나는 xy 문제에 유죄 일 수는 있지만 정교하게 노력할 것이다. Miku는 내가 원하는 것을 거의 가지고있다. 덧붙여 말하면 나는 덧셈 과정을 밟고있다 : 두 개의 예제 호출 후에'e.attributes'를 갱신하여 그 값이 '{'i_am_totally_different ':'yes, indeed ' '이름': 'myevent', '범주': '범주 값', '분류': '분류 값', '번호': 42} '. Mike의 질문에 답하기 위해, 처음에는'e'를 만들 때 모든 클래스에 필요한 모든 정보를 가지지 않았을 수도 있습니다.하지만 나는 단편적 업데이트 속성을 원하지 않습니다. – verbsintransit

답변

1

, 당신은 info의 구조의 Event 완전히 무지 확인하기 위해 예에 필요한 것이 무엇 인 파이썬 객체의 no totally clean way to get only user defined attributes있다. 그리고 설계가 해킹으로 만 실현 가능하다면, OOD-ish로 보일지라도 가장 강력하지는 않을 것입니다.

class Event(object): 
    # instead of accepting attributes, just deal with a single object 'info' 
    def __init__(self, name, info): 
     self.name = name 
     self.info = info 

    @property 
    def attributes(self): 
     # attributes will consist of 
     # A) Event's name - fixed 
     # B) info objects hopefully 'public' attributes, which we need 
     # to lookup at runtime 
     attrs = {'name': self.name} 
     for attr in [name for name in dir(self.info) 
        if not name.startswith('_')]: 
      attrs[attr] = getattr(self.info, attr) 
     return attrs 

Class1Class2 정말 많이 공유하지 않는 :

class Class1(object): 
    def __init__(self, some_number): 
     # some initial attribute 
     self.number = some_number 

    @property 
    def category(self): 
     # stuff 
     return 'category value' 

    @property 
    def classification(self): 
     # stuff 
     return 'classification value' 

class Class2(object): 
    @property 
    def i_am_totally_different(self): 
     return 'yes, indeed' 
를 이벤트 클래스의 예를 아래

, 즉 전달 된 info 객체의 실제 속성의 무지

이제 이벤트로 모든 클래스를 전달할 수 있지만, 정말 귀하의 질문이라면 나는 확실하지 않다 :

e = Event('myevent', Class1(42)) 
print(e.attributes) 
# {'category': 'category value', 'name': 'myevent', 
# 'classification': 'classification value', 'number': 42} 

e = Event('myevent', Class2()) 
print(e.attributes) 
# {'i_am_totally_different': 'yes, indeed', 'name': 'myevent'} 
0

당신은 '나는 두 개의 클래스가 있습니다 : 하나는 이벤트를위한 것이고 다른 하나는 그 이벤트의 속성 집합을 계산하는 것입니다.'라고 말합니다. 이럴 이유가 있습니까? 이벤트 클래스가있는 경우 계산 된 속성을 이벤트의 속성으로 사용하지 않는 이유는 무엇입니까?

+0

제 원래 질문에서 내 의견을 참조하십시오. – verbsintransit

+0

@verbsintransit이 대답했습니다 - 아주 간단한 문제에 대한 * 매우 복잡한 해결책을 찾으려고합니다. 해결하려는 실제 문제에 대해 더 자세히 설명하면이 모든 내성 검사를 사용하는 것보다 해결 방법을 더 잘 조사 할 수 있습니다. 거대하고 복잡한 응용 프로그램은 파이썬에서 존재하며이 글꼴은이 해킹 된 내부 논리를 사용하지 않습니다. –

0

이 향한 또 다른 방법은 무엇인지 모른 채 강좌 2 강좌 3 등의 전체 내용을 덤프하지 않을 것입니다. 예를 들어 'get_attributes'메소드를 사용하여 클래스가 '공개'속성을 게시하는 것으로 기대할 수 있습니다. 코딩 편의 관점에서 그것은 강좌 2 강좌 3 경우 등 공통 조상으로부터 상속에 적은 작업입니다하지만 '오리 액세스'로 완벽하게 OK입니다 그들 :

class Event(object): 
    def __init__(self, name, info): 
     self.Name = name 
     self.Info = info 

    @property 
    def attributes(): 
     result = { k: getattr(info, k) for k in info.get_attributes() } 
     return result 

class Class1(object): 
    def __init__ (name, classification, other) 
     self.Name = name 
     self.Other = other 
     self.Classification = classification 

    def get_attributes(self): 
     return ("Name", "Classification") # in this case not "Other"... 

class Class2(object): 
    def __init__(self, privateName, orivateData, publicName): 
     self.Name = privateName 
     self.Data = privateData 
     self.Public = publicName 

    def get_attributes(self): 
     return ("Public",) 

이 @ 미쿠의 아이디어 얼터너티브 '옵트 인'이다 이벤트> 정보 관계의 양 끝에 코드를 작성하는 유일한 사람이 확실하지 않으면 아마 안전한 베팅 일 것입니다. 멋진 트릭은 데코레이터를 제공하여 get_attributes 메소드로 기존 클래스를 수정하는 것입니다.이 것 : 옆 의도

선명도,이 또한 필드 :

는 @ 마이크의 관찰에 대응

편집 중 하나의 텍스트 천 라인 괴짜 클래스로 실행에 대한 약간의 보호입니다 get_attributes가 정보 객체에서 사전을 방금 반환 한 경우 클리너가되어 반사 부담이없는 순수한 디커플링이됩니다. 나는 코드를 그대로 두거나 토론이 이해가되지 않지만 올바른 방법은 존재한다면 'get_attributes'를 호출하고 그렇지 않으면 기본값을 반환하는 것입니다. 내 나쁜 :)

+0

이름과 데이터는 Class2에서 어떻게 비공개입니까? 또한 클래스를 Event에 전달하지 않아도됩니까? 이러한 문제는 제쳐두고, 이런 종류의 디자인은 매우 해킹됩니다. OP가 근본적으로 달성하기를 원하는 것보다 나은 솔루션이 있어야합니다. –

+0

개인 정보 보호는 순전히 개념적입니다. 단지 이벤트 시스템에 게시되지 않는다는 것을 나타내는 것입니다. 요점은 OP가 원하는 것이 너무 완벽하기 때문에 문제가 해결 될 가능성이 더 높다는 것입니다. 완전한 디커플링은 그것을 달성 할 수있는 유일한 방법이 알려지지 않은 클래스의 내부에 대한 상세한 반영 인 경우 매우 유용하지 않습니다. – theodox

+0

파이썬에서 프라이버시를 나타내는 표준 방법은 앞에 오는 두 번째 밑줄입니다 (예 : self .__ 이름의 경우). –