Уведомления

Группа в Telegram: @pythonsu

#1 Март 25, 2013 16:01:30

soln
От:
Зарегистрирован: 2011-11-02
Сообщения: 42
Репутация: +  0  -
Профиль   Отправить e-mail  

Область видимости декоратора.

Здравствуйте.
Возник вопрос.

А как устроена область видимости декоратора?

 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.



Отредактировано soln (Март 25, 2013 16:49:24)

Офлайн

#2 Март 25, 2013 17:16:18

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Область видимости декоратора.

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

Отредактировано sergeek (Март 25, 2013 17:16:36)

Офлайн

#3 Март 26, 2013 11:53:04

soln
От:
Зарегистрирован: 2011-11-02
Сообщения: 42
Репутация: +  0  -
Профиль   Отправить e-mail  

Область видимости декоратора.

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
посчитай вручную и поймешь

Не понял Вас что считать?



Отредактировано soln (Март 26, 2013 11:53:27)

Офлайн

#4 Март 26, 2013 12:24:11

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Область видимости декоратора.

Локальные объявления перекрывают глобальные.
Оборачиваемая функция передается в декоратор как параметр - почему она должна при этом видеть объявления декоратора?

Офлайн

#5 Март 26, 2013 12:58:41

soln
От:
Зарегистрирован: 2011-11-02
Сообщения: 42
Репутация: +  0  -
Профиль   Отправить e-mail  

Область видимости декоратора.

Кажется я понял. Спасибо.
Декоратору передается объект функции с уже запакованной областью видимости.

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



Отредактировано soln (Март 26, 2013 13:15:11)

Офлайн

#6 Март 26, 2013 13:12:33

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Область видимости декоратора.

Кроме того, что среда питона использует декораторы как декораторы, в остальном они обычные функции.

Офлайн

#7 Март 26, 2013 13:35:01

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Область видимости декоратора.

Даже вот так работает:

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()

Офлайн

#8 Март 27, 2013 02:01:45

krishnarama
Зарегистрирован: 2013-02-27
Сообщения: 51
Репутация: +  -36  -
Профиль   Отправить e-mail  

Область видимости декоратора.

Вставляю пост выше в интерпретатор питона 2.7 - матерится. Что такое?

Офлайн

#9 Март 27, 2013 07:48:36

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Область видимости декоратора.

У меня всё работает.

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

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version