2010-06-13 8 views
0

필자는 다른 사람들의 코드를보기 전에 필자가 만든 메모 작성기 버전을 쓰려고 시도하면서 깊이 놀아왔다. 솔직히 재미있게 운동 할 수 있습니다. 그러나 주위를 놀면서 나는 내가 꾸미는 사람들과 내가 원하는 것을 할 수 없다는 것을 발견했다.데코레이터에서 명명 된 키워드는 무엇입니까?

def addValue(func, val): 
    def add(x): 
     return func(x) + val 
    return add 

@addValue(val=4) 
def computeSomething(x): 
    #function gets defined 

내가이 일을 가지고 수행 할 경우

def addTwo(func): 
    return addValue(func, 2) 

@addTwo 
def computeSomething(x): 
    #function gets defined 

이유는이 방식으로 장식하여 키워드 인수를 사용할 수 없습니다? 내가 뭘 잘못하고 있고 내가 어떻게해야하는지 가르쳐 줄 수 있니? 당신이 @addTwo을 쓸 때

def addValue(val): 
    def decorator(func): 
     def add(x): 
      return func(x) + val 
     return add 
    return decorator 

, addTwo의 값이 직접 장식으로 사용됩니다

답변

5

당신은 장식을 반환하는 함수를 정의해야합니다. 그러나 @addValue(4)이라고 쓰면 먼저 addValue(4)이 addValue 함수를 호출하여 평가됩니다. 그런 다음 결과가 데코레이터로 사용됩니다.

+0

그래서 파이썬 장식에서 열망하는 평가를 사용한다고 말하는 것입니까? 이 얼마나 나쁜가. – wheaties

5

당신은 부분적으로에게 기능 addValue 적용 원하는 - val 인수를 제공,하지만하지 func. 첫 번째는을 무두질 에게 전화를 interjay의 대답에 사용되는

:이 작업을 수행하는 두 가지 방법이 일반적이 있습니다 대신 두 개의 인수, f(a,b) -> res와 기능, 당신은 다른 함수를 반환하는 첫 번째 인수의 함수를 작성하는 두 번째 인수를받습니다. g(a) -> (h(b) -> res)

다른 방법은 functools.partial 개체입니다. 함수에 대한 검사를 사용하여 함수를 실행해야하는 인수를 찾습니다 (funcval). 부분을 ​​만들 때 추가 인수를 추가 할 수 있으며 부분을 호출하면 추가 인수를 모두 사용합니다.

from functools import partial 
@partial(addValue, val=2) # you can call this addTwo 
def computeSomething(x): 
    return x 

파셜 특히 하나 개 이상의 인수로, 일반적으로이 부분 응용 프로그램 문제에 대한 훨씬 간단 솔루션입니다. 인수 어떤가지와

+0

functools.partial, 아주 좋습니다. 들여 쓰기를 세 번하지 않고도 파이썬에서 완성 된 커링을 얻을 수있는 간단한 방법이 있다는 것을 알고있었습니다. 감사합니다. – wheaties

3

장식 - 이름/키워드들, 이름/위치들, 또는 각의 일부 - 기본적으로, 사람 당신에게 @name 라인 전화보다는이 단지 언급을 - double 중첩 수준 (방금 언급 한 데코레이터에는 중첩 수준이 하나만 있음)이 필요합니다.

def double(): 
    def middling(): 
    def inner(f): 
     return f 
    return inner 
    return middling 

당신은

으로 사용할 것 : 여기 간단한 수행 아무것도 두 번 중첩 된 장식이 - 당신은 @ 라인 전화 그들에게 원하는 경우 그 인수가없는 사람에 대해서도 간다 (이 경우 비어가 필요한 인수가되지도 원부터)
@double() 
def whatever ... 

참고 괄호 : 그들은 당신이 whatever을 장식하는 middling을 반환double를 호출하고 의미한다. 당신이 (예를 들어 옵션)라는 이름의 인수를 추가, "전화"와 "방금 언급"의 차이를 본 적이되면

하드되지 않습니다 :

def doublet(foo=23): 
    def middling(): 
    def inner(f): 
     return f 
    return inner 
    return middling 

가능한 중 하나로서 :

@doublet() 
def whatever ... 

또는 :

@doublet(foo=45) 
def whatever ... 

또는 등가로서 : 0

@doublet(45) 
def whatever ...