Найти - Пользователи
Полная версия: Область видимости декоратора.
Начало » Python для новичков » Область видимости декоратора.
1
soln
Здравствуйте.
Возник вопрос.

А как устроена область видимости декоратора?
 var = 'glob'
 
 def decor(func):
     var = 'in_func decor'
     def wripper():
         var = 'in_func wripper'
         return func()
     return wripper
 
 @decor
 def xxx():
     print var
 xxx()

Данный код вернул >>> glob , чем озадачил меня, я как то ожидал увидеть in_func wripper.
sergeek
soln
А как устроена область видимости декоратора?
так же как у функции
оно просто разворачивается в
 
def xxx():
     print var
xxx = decor(xxx)
посчитай вручную и поймешь, что именно это он и должен выводить
soln
sergeek
так же как у функции

Ммм…
Так нет же?
In [24]: def decor():
   ....:     var = 'in_func decor'
   ....:     def wripper():
   ....:         var = 'in_func wripper'
   ....:         print var
   ....:     wripper()
In [25]: decor()
in_func wripper
In [26]: var = 'glob'
In [27]: decor()
in_func wripper

sergeek
посчитай вручную и поймешь

Не понял Вас что считать?
Shaman
Локальные объявления перекрывают глобальные.
Оборачиваемая функция передается в декоратор как параметр - почему она должна при этом видеть объявления декоратора?
soln
Кажется я понял. Спасибо.
Декоратору передается объект функции с уже запакованной областью видимости.
var = 'glob'
 
 def decor(func):
     var = 'in_func decor'
     def wripper():
         var = 'in_func wripper'
         print func.__globals__['var']
 #        return func()
     return wripper
 
 #xxx = decor(xxx)
 
 @decor 
 def xxx(): 
     print var  
      
 print xxx.__globals__['var'] 
 xxx()

Возвращает
>>> glob
>>> glob

Тогда у меня возникает другой вопрос.
Если я хочу переопределить поведение функции передаваемой декоратору, можно поступить так?

 var = 'glob'
 
 def decor(func):
     var = 'in_func decor'
     def wripper():
         var = 'in_func wripper'
         func.__globals__['var'] = var
         return func()
     return wripper
 
 #xxx = decor(xxx)
 
 @decor
 def xxx():
     print var 
     
 print xxx.__globals__['var']
 xxx()
возвращает
>>>glob
>>>in_func wrippe
Shaman
Кроме того, что среда питона использует декораторы как декораторы, в остальном они обычные функции.
Shaman
Даже вот так работает:
class decor():
    def __call__(self, func):
        def wrapper():
            var = 'in_func wrapper'
            print var
            return func()
        return wrapper
newc=decor()
d=newc
@d
def myf():
    print 123
myf()
krishnarama
Вставляю пост выше в интерпретатор питона 2.7 - матерится. Что такое?
Shaman
У меня всё работает.
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
in_func wrapper
123
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB