2011-02-14 2 views
11

동일한 클래스의 새 인스턴스를 반환하는 객체에 대한 메소드가 있습니다. 이 메서드를 작성하는 가장 관용적 인 방법을 알아 내려고 노력 중이므로 코드를 복제하지 않고 동일한 유형의 새 개체를 생성합니다. 이 방법은 인스턴스에서 데이터를 사용하기 때문에클래스 내에서 새 객체를 생성하는 관용적 Python

, 내 첫 번째 패스는 다음과 같습니다

class Foo(object): 
    def get_new(self): 
     data = # Do interesting things 
     return Foo(data) 

그러나, 나는 푸를 서브 클래스와 푸 반환 SubFoo에 get_new 전화, get_new 오버라이드 (override)하지 않는 경우! 그래서, 나는 classmethod 작성할 수

class Foo(object): 

    @classmethod 
    def get_new(cls, obj): 
     data = # Munge about in objects internals 
     return cls(data) 

그러나, 나는이 접근하고있어 데이터가 객체에 특정한를, 그래서 "보통"(장식되지 않은) 방법으로하지 이것에 대한 캡슐을 깰 것으로 보인다. 또한 SubFoo.get_new(sub_foo_inst)과 같이 호출해야합니다. 개체가 반환 할 형식을 "알기"만하면됩니다. - 자체와 같은 형식입니다.

클래스에 팩토리 메소드를 추가하고 로직을 복제하지 않고 모든 곳에서 리턴 유형을 대체 할 수 있다고 가정합니다.하지만 이는 서브 클래스에서 많은 작업을 수행하는 것처럼 보입니다.

그럼 내 질문은 모든 곳에서 유형에 주석을 달지 않고도 클래스 유형에 유연성을 제공하는 메소드를 작성하는 가장 좋은 방법은 무엇입니까?

+0

classmethod는 파이썬에서 매우 관용적이지 않습니다. 팩토리는 클래스와 동일한 모듈에있는 일반 함수 일 수 있습니다. –

+1

@Adam : 클래스 메소드에는 용도가 있습니다 (예 : 클래스 변수를 사용하고 상속을 중단하지 않으려는 경우). 정적 방법은 훨씬 더 나쁩니다. – delnan

답변

16

당신이 하위 클래스에 대한 더 유연하게하려면, 당신은 단순히 self.__class__ 특별한 속성 사용할 수 있습니다 다음 @classmethod 접근 방식을 사용하여 그것을 제거, 어느 하나 개의 인스턴스 내에서 데이터에 액세스 할 수 것

class Foo(object): 
    def __init__(self, data): 
     self.data = data 

    def get_new(self): 
     data = # Do interesting things 
     return self.__class__(data) 

#Do interesting things이 인스턴스 내에 저장된 데이터에 의존하는 경우에 실행 가능한 솔루션으로 사용할 수 있습니다. 파이썬 3

>>> class Foo: 
...  pass 
... 
>>> f = Foo() 
>>> type(f) 
<type 'instance'> 
>>> f.__class__ # Note that the __class__ attribute still works 
<class '__main__.Foo'> 

는,이되지 않습니다 :이 (즉, 기본 object에서 서브 클래스되지 않은이) classic classes에 대한 부적절한 값을 반환로

파이썬 2, 난, type(self)을 사용하지 않는 것이 좋습니다 그러나 모든 클래스가 object에서 파생됨에 따라 self.__class__은 Pythonic 관용구로 간주됩니다.

+0

완벽한! 그게 바로 제가 찾던 것입니다. 이것은 파이썬을 심각하게 사용하는 2, 3 주 밖에되지 않으므로 모든 조각과 사용법을 완전히 알지 못합니다. –

+1

möter가 말했듯이'type (self)'를 사용하는 것은 본질적으로 똑같은 일을하지만 약간 더 깨끗한 IMHO입니다. 하지만 어쩌면 그것은 네 가지 밑줄이있는 것에 대한 나의 혐오 일뿐입니다. – Thomas

+2

@ 토마스 : 사실'type()'을 사용하지 않는 것이 좋습니다. 왜 대답했는지에 대한 설명을 추가했습니다. – gotgenes

2

내장 '유형'을 사용할 수 있습니다.

type(instance) 

은 해당 인스턴스의 클래스입니다.

관련 문제