还是请教装饰语法的问题

还是请教装饰语法的问题

看了limodo的解说和些网上的帖子,还是搞不懂。
都是说:
◎a
def b:pass
等同于b=a(b)
可我测试了下很不理解。请高手指教!谢谢
--------------------------
一,测试函数参数传递:
def e(f):
        def ee(*args,**dic):
                print("begin ee")
                f(*args,**dic)
                print("ee is :")
        print("e begin")
        return ee
def b(n):
        for x in range(n):print(x)
e(b(5))
0
1
2
3
4
e begin
<function ee at 0x0144CCD8>
其中e函数里的return语句可以省略,可是搞不懂,为什么执行了定义ee函数语句块里的f(*args,**dic),却不执行前后两个print语句。
-------------------------------
二,测试修饰语句:
def ae(f):
        def ee(*args,**dic):
                print("begin ee")
                f(*args,**dic)
                print("ee is :")
        print("ae begin")
        return ee
@ae
def ab(n):
        for x in range(n):print(x)
可是运行ab(5)时出现的结果是:
ab(5)
begin ee
0
1
2
3
4
ee is :
这回执行了ee函数定义语句块中的前后两个print语句了,可是ae的print("ae begin")却不执行了?
而且用ae里不能省略 return ee语句。
====================
真是给搞糊涂了
e(b(5)),你的原意应该是e(b)吧……
e(b(5))传递的是b(5)的返回值,就是None,而打印0到4是因为b(5)调用了函数b。
第一个函数调用明白了,不是它执行了def ee里面的语句,是传递b函数时已经执行


QUOTE:
原帖由 jjj137 于 2008-9-20 13:13 发表
e(b(5)),你的原意应该是e(b)吧……
e(b(5))传递的是b(5)的返回值,就是None,而打印0到4是因为b(5)调用了函数b。

谢谢!
正是如你所说,真的搞蒙了。调用函数应该是e(b),这样才能在e里面使用b
貌似只有ae中return的函数才会被执行,ae中的语句在@ae时就执行了……
没用过修饰器,具体不知道什么原理。
哪位高手写下修饰语法的流程图就好了
你第二个例子的 ae begin应该要打印出来才对


QUOTE:
原帖由 bluecrystal 于 2008-9-20 14:38 发表
你第二个例子的 ae begin应该要打印出来才对

我试试了下,后面如果再执行ab(5)应该是不打印出来“ ae gegin"
我刚试了不带参数的:
>>> def q(f):
        print("begin q")
        x=f()
        print(x)
        def new():
                print("begin new")
                x=10
                print(x)
                print("end new")
        return new

>>> @q
def qq():
        print("begin qq")
        x=5
        print("end qq")

       
begin q
begin qq
end qq
None
>>> qq
<function new at 0x01477228>
>>> qq()
begin new
10
end new
>>>
------------------
我个人总结是:(暂且把q函数叫做母函数)
把qq函数传递给q,q处理后,一定要返回一个跟qq同型的函数,最后执行此返回的函数,就告结束。母函数q里面的非返回函数代码部分只在定义@时执行一次,之后qq就不再是定义它时的代码,而是母函数返回的函数。
你最好把所有代码都放到一个文本里面来写,不要再python shell里面执行,用文件来测试你的代码,@decorator修饰符应该放在你所定义的函数的前面一行
我们来看python2.5 documentation里面关于函数以及@的原文说明:
The function definition does not execute the function body; this gets executed only when the function is called.
一个函数只有在被调用的时候才会执行,而函数定义本身(简单点来说就是函数名吧)并不会执行函数内的代码,我自己加点说明(函数名就是一个符号,它只有跟操作代码绑定到一起,才会起到作用)
A function definition may be wrapped by one or more decorator expressions. Decorator expressions are evaluated when the function is defined, in the scope that contains the function definition. The result must be a callable, which is invoked with the function object as the only argument. The returned value is bound to the function name instead of the function object. Multiple decorators are applied in nested fashion. For example, the following code:
一个函数定义可以被多个decorator修饰。decorator修饰实际上就是对函数名进行操作,并把函数名重新绑定到新的函数执行代码,这就是为什么你的修饰函数必须返回一个函数的原因


@f1(arg)
@f2
def func(): pass

is equivalent to:


def func(): pass
func = f1(arg)(f2(func))
这个例子还原了修饰符的本来最原始的写法

实际上你可以这样来看,当你在代码中调用func()实际上就是f1(arg)(f2(func))()