3

데코레이터 내부의 함수 속성에 액세스 할 수 있습니까? 아래 코드를 고려하십시오.데코레이터 내부의 함수 속성에 액세스

def deco(a): 
    def wrap(): 
     print(a.status) 
     a() 
     print(a.status) 



    return wrap 


@deco 
def fun1(): 
    fun1.status="bar" 


fun1.status="foo" 
fun1() 

나는 수 출력을 예상 :

foo 
bar 

하지만 아래의 오류 얻을 :

Traceback (most recent call last): 
    File "<pyshell#0>", line 1, in <module> 
    fun1() 
    File "D:\python_projects\test_suite\func_attribute.py", line 3, in wrap 
    print(a.status) 
AttributeError: 'function' object has no attribute 'status' 

때문에이 일을 어떤 방법이 있나요을

def fun1(): 
    fun1.status="bar" 


fun1.status="foo" 

a=fun1 

print(a.status) 
a() 
print(a.status) 

출력 :

foo 
bar 

예상대로.

답변

1

데코레이터 덕분에 글로벌 이름 fun1장식 결과에 바인딩되므로 중첩 된 wrap() 함수 개체에 바인딩됩니다. 그러나 내부 wrap() 안에, a원래, unwrapped 함수 객체를 나타냅니다.

그래서 개의 서로 다른 함수 객체이 있으며 각각은 속성을 가질 수 있습니다. 그들은 같은 대상이 아닙니다. fun1.statusa.status과 다른 속성입니다.

당신은 wrap으로 장식에 fun1 같은 개체에 액세스 할 수 있습니다

print(wrap.status) 

데모 :

>>> def deco(a): 
...  def wrap(): 
...   print(wrap.status) 
...   a() 
...   print(wrap.status) 
...  return wrap 
... 
>>> @deco 
... def fun1(): 
...  fun1.status="bar" 
... 
>>> fun1.status="foo" 
>>> fun1() 
foo 
bar 
+0

데프 데코 (A) : 인쇄 (fun1 : 데프 (을) 포장. 상태) a() print (fun1.status) 반송 랩 @deco def fun1() : fun1.status = "bar" fun1.status = "foo" fun1() –

+0

위의 코드도 작동합니다. Interesting –

+0

@SudhanNadar : 그렇습니다. 왜냐하면 데코레이터가 목표로 삼는 글로벌'fun1' 이름을 참조하기 때문입니다. 그러나 이제는 장식 한 * 함수에 바인딩됩니다. 다른 함수'fun2'에서 데코레이터를 사용할 수없고 호출 할 때 두 번째 함수 객체의 속성에 액세스 할 수 있습니다. 'wrap'은 항상 장식 결과에 대한 올바른 참조가 될 것입니다. –

관련 문제