2013-10-15 7 views
0

메서드 데코레이터를 작성 중이며 현재 데코 레이팅 된 메서드를 정의하는 클래스에 액세스해야합니다.클래스 포함 메서드 받기

이 문제는 클래스의 파이썬 3 메소드가 클래스가 인스턴스화되지 않는 한 단지 함수라고 보입니다.

이 문제가 발생합니까? 시 방법에 대한 당신의 장식이 실행되기 때문에 정말 클래스가을 만들 수 아직, 당신은 할 수 없습니다 ... __qualname__ 주변에 바이올린

In [29]: class A: 
    ....:  def B(self): 
    ....:   pass 
    ....:  

In [30]: A.B.__qualname__ 
Out[30]: 'A.B' 

# This is what I want: 
>>> get_class(A.B) 
A 
+2

대신 클래스 데코레이터를 만들지 않으시겠습니까? 클래스 본문에 함수를 꾸미면 * 클래스가 아직 생성되지 않습니다 *. –

+0

@MartijnPieters 데코레이터가 데코 레이팅 된 메소드 *의 의미를 포함하는 클래스 *에 비례하므로 변경합니다. '@decorate ("some_method") \ nclass Foo : ...는 매우 반 직관적 인 것처럼 보입니다. 대안이 없다면 커스텀 기본 클래스 나 메타 클래스를 만들고 거기에있는 모든 메소드의 속성을 검사 할 것입니다. 아니면 비슷한. – dom0

+0

@ Michael0x2a : 아니, 올바른 복제가 아닙니다. 메소드의 함수 장식자는 모든 함수가 정의 될 때까지 클래스 객체가 없으므로 * 아직 * 클래스를 결정할 수 없습니다. –

답변

1

를 원하지 않는다.

예는이 조금 더 보여

spam(bar)가 장식 된 기능을 생산하기 위해 호출
class Foo: 
    @spam 
    def bar(self): pass 

, 우리는 파이썬 클래스 본문을 정의하기 위해 실행하는 가상 함수 내에서입니다. 해당 의사 함수 실행이 완료 될 때만 해당 함수의 로컬 네임 스페이스가 클래스 본문으로 변환되고 실제 클래스 개체 자체가 만들어집니다.

즉, spam()이 실행될 때 Foo 클래스 개체가 아직 없음을 의미합니다.

대신, 클래스 장식을 만들 :

@spam 
class Foo: 
    def bar(self): pass 

지금 spam() 전체를 통과, 전체 Foo 클래스를 사용하면 클래스와 방법 모두에 대한 액세스를 제공합니다.

당신이 장식 클래스에 대한 구체적인 방법을 표시해야하는 경우 기능에 속성을 설정하는 마커 장식 사용할 수 있습니다

def marker(func): 
    func._marked = True 
    return func 

사용 당신이 장식하려는 방법에 대한 클래스 몸이 데코레이터 그런 다음 클래스 데코레이터를 사용하여 해당 메소드를 선택하십시오.

@spam 
class Foo: 
    @marker 
    def bar(self): pass 

    def baz(self): pass 
+0

그러나 데코레이터는 이것을 달성하기 위해'self .__ class______name__'을 사용할 수 없습니까? 내 말은, op는 장식자가 할 일을 언급하지 않는다. –

+0

@PauloBu : 일단 바인딩하면 이미 클래스가 있습니다. '유형 (자기)', 이름을 붙잡기 위하여 갈 필요도. 그것은 여기서 문제가되지 않습니다. –

+0

죄송합니다. 제 의견을 말하기 위해'.__ name__'을 추가합니다. 내가 언급 한 것은 - 의심 스럽지만 - 메소드 데코레이터가'self' 매개 변수를 사용하여 메소드의 클래스에 액세스 할 수 있다는 것입니다. 그는 여전히 데코레이터를 사용할 수 있으며 클래스에 액세스 할 수 있습니다. _the 클래스가 아직 생성되지 않은 경우에도 메소드가 실행될 때 데코레이터는'self .__ class__'에 액세스하고 그 작업을 할 수 있습니다. –

관련 문제