2011-08-11 5 views
30

클래스 데코레이터와 메소드 데코레이터를 멋지게 함께 플레이 할 때이 동작에 부딪 혔습니다. 본질적으로, 메소드 데코레이터는 일부 더미 값으로 메소드의 일부를 특별하게 플래그 지정하고, 클래스 데코레이터는 이후에 와서 값을 나중에 채 웁니다. 이것은 간단한 예를하다Python에서 instancemethods에 속성 추가하기

>>> class cow: 
>>>  def moo(self): 
>>>   print 'mooo' 
>>>  moo.thing = 10 
>>> 
>>> cow.moo.thing 
10 
>>> cow().moo.thing 
10 
>>> cow.moo.thing = 5 
AttributeError: 'instancemethod' object has no attribute 'thing' 
>>> cow().moo.thing = 5 
AttributeError: 'instancemethod' object has no attribute 'thing' 
>>> cow.moo.__func__.thing = 5 
>>> cow.moo.thing 
5 
cow.moo.thing = 5이 작동하지 않는 이유

사람이 cow.moo.thing은 아주 명확하게 (10)는 나에게 준다해도, 알고 있나요? 그리고 왜 cow.moo.__func__.thing = 5이 효과가 있습니까? 왜 그런지 전혀 모르지만 갑자기 무언가를 얻으려고 시도한 dir(cow.moo) 목록의 내용을 무작위로 들으며 무언가를 알 수 없습니다.

답변

33

속성 조회를 위해 Python은 자동으로 인스턴스 메소드에 연결된 실제 함수를 사용합니다.

속성 설정의 경우 그렇지 않습니다.

두 연산자는 모두 . 연산자를 사용하지만 명령문의 어느쪽에 따라 두 개의 별도 연산입니다.

인스턴스 메소드의 __func__에 액세스하면 실제로 moo 속성이있는 실제 함수에 수동으로 액세스 할 수 있습니다.

파이썬 3에서는 메소드가 기본적으로 함수이기 때문에 원하는대로 작동합니다.

+0

아, 나도 몰랐다. 감사! –

+0

파이썬 3에서 오래된 게시물을 되살려 주어 죄송합니다.'cow(). moo.thing = 5'는'AttributeError : 'method'객체에 'thing'속성이 없습니다. 왜 그런지 알아? –

+0

@JacquesGaudin 인스턴스 ('cow(). moo')에서 함수는 모든 버전의 Python에서 메서드 객체로 래핑됩니다. 차이점은 클래스 ('cow.moo')에서 파이썬 3으로 래핑되지 않았습니다. 랩핑은'self'가 함수에 자동으로 전달되도록하는데 필요합니다. – agf

3

C에서 함수와 인스턴스 메소드의 함수 속성을 수정하려는 경우 가지고있는 호출 가능 유형을 확인해야합니다.

그래서 당신은 당신이 이런 식으로 확인할 수 있습니다 호출의 몇 가지 유형의의 PyObject을 한 가정 :

PyObject *callable; // set to something callable 
PyObject *setting; // set to something 
if(PyMethod_Check(callable)){ 
    PyObject_SetAttrString(PyMethod_Function(callable),"attribute",setting); 
}else{ 
    PyObject_SetAttrString(callable,"attribute",setting); 
} 
... 
// and the inverse 
if(PyMethod_Check(callable){   
    if(PyObject_HasAttrString(PyMethod_Function(callable),"attribute")){ 
     PyObject_DelAttrString(PyMethod_Function(callable),"attribute"); 
    } 
    }else{ 
    if(PyObject_HasAttrString(callable,"attribute")){ 
     PyObject_DelAttrString(callable,"attribute"); 
    } 
    } 

이제 코드 AGF는 인스턴스 메소드 파이썬 내에서 작품을 지적했다. 방금 인스턴스 메소드의 속성을 설정하려고하면 아무리 파이썬에서 액세스하려고해도 속성을 찾을 수 없습니다.

나는이 문제에 부딪 쳤고 AGH의 대답에 대한 Li Haoyi의 질문은 내가 무엇이 바뀌어야 하는지를 이해하는 데 도움이되었다. 나는 C.을 통해이 문제를 해결하는 방법을 찾고있는 동안 누군가가이 질문을 발견하고 다시 대답한다 생각

편집 : 참고 :이 파이썬 2.7.x.입니다 Python 3.x는 다른 함수 호출을 사용합니다.