파이썬 클래스 메서드 꾸미기-인스턴스를 데코레이터에 어떻게 전달합니까?
이것은 Python 2.5이며 GAE 도 중요하지 않습니다.
다음 코드가 있습니다. dec_check 클래스를 데코레이터로 사용하여 foo () 메서드를 bar로 데코레이션하고 있습니다.
class dec_check(object):
def __init__(self, f):
self.func = f
def __call__(self):
print 'In dec_check.__init__()'
self.func()
class bar(object):
@dec_check
def foo(self):
print 'In bar.foo()'
b = bar()
b.foo()
이것을 실행할 때 나는보고 싶었다.
In dec_check.__init__()
In bar.foo()
그러나 나는 " TypeError: foo() takes exactly 1 argument (0 given)
"를 얻고 .foo()
있다. 객체 메소드이기 때문에 self를 인자로 취한다. 나는 bar
데코레이터 코드를 실행할 때 의 인스턴스 가 실제로 존재하지 않는다는 것이 문제라고 생각 합니다.
그렇다면 bar
데코레이터 클래스에 의 인스턴스를 어떻게 전달 합니까?
당신은으로 장식을해야 기술자 중 하나는 (메타)을 보장함으로써 클래스는이 - __get__
방법, 또는 방법으로 간단을, 데코레이터를 사용하여 기능을 대신 데코레이터 클래스를 (함수가 이미 기술자이기 때문에). 예 :
def dec_check(f):
def deco(self):
print 'In deco'
f(self)
return deco
class bar(object):
@dec_check
def foo(self):
print 'in bar.foo'
b = bar()
b.foo()
이것은 인쇄
In deco
in bar.foo
바라는대로.
Alex의 대답은 함수가 충분할 때 충분합니다. 그러나 클래스가 필요할 때 데코레이터 클래스에 다음 메서드를 추가하여 작동하도록 만들 수 있습니다.
def __get__(self, obj, objtype):
"""Support instance methods."""
import functools
return functools.partial(self.__call__, obj)
이것을 이해하려면 디스크립터 프로토콜을 이해해야합니다. 설명자 프로토콜은 사물을 인스턴스에 바인딩하는 메커니즘입니다. __ get __, __ set __ 및 __ delete __로 구성되며, 인스턴스 사전에서 사물을 가져 오거나 설정하거나 삭제할 때 호출됩니다.
이 경우 인스턴스에서 물건을 가져 왔을 때 부분을 사용하여 __ call __ 메서드의 첫 번째 인수를 인스턴스에 바인딩합니다. 이것은 클래스가 생성 될 때 멤버 함수에 대해 자동으로 수행되지만 이와 같은 합성 멤버 함수의 경우 명시 적으로 수행해야합니다.
데코레이터는 파이썬에서 약간 까다로울 수 있습니다. 언젠가 다시 일하게 된 사례가 있습니다. 당신이하려는 것을 추론 할 수있을 것입니다.
데코레이터를 클래스로 작성하려면 다음을 수행 할 수 있습니다.
from functools import update_wrapper, partial
class MyDecorator(object):
def __init__(self, func):
update_wrapper(self, func)
self.func = func
def __get__(self, obj, objtype):
"""Support instance methods."""
return functools.partial(self.__call__, obj)
def __call__(self, obj, *args, **kwargs):
print('Logic here')
return self.func(obj, *args, **kwargs)
my_decorator = MyDecorator
class MyClass(object):
@my_decorator
def my_method(self):
pass
'developer tip' 카테고리의 다른 글
web.config에서 프록시 자격 증명을 지정할 수 있습니까? (0) | 2020.12.11 |
---|---|
jQuery의 배열에 항목을 어떻게 추가합니까? (0) | 2020.12.11 |
작동하는 JSLint Eclipse 플러그인이 있습니까? (0) | 2020.12.11 |
Ruby on Rails 3-각 요청에 대해 lib 디렉토리 다시로드 (0) | 2020.12.11 |
java.sql.Connection에서 데이터베이스 URL을 얻는 방법은 무엇입니까? (0) | 2020.12.11 |