Python脚本如何执行?

时间:2014-12-09 09:32:02

标签: python python-decorators

我有一个以下的小型Python程序:

def wrap(func):
    print "before execution ..."
    a = func()
    print "after execution ..."
    return a


@wrap
def dosomething():
    print "doing something ..."

当我执行上面的脚本时,我不应该得到任何输出,因为我没有打电话:

  

DoSomething的()

但是当我执行这个脚本时,我得到以下输出:

before execution ...
doing something ...
after execution ...

请解释此行为的原因

5 个答案:

答案 0 :(得分:3)

当您使用@时,您正在装饰您正在使用其他功能进行注释的功能。使用装饰器语法时会调用装饰器外部函数 - 这是有道理的。

如果你想制作一个真正的装饰器,你需要将dosomething()调用包装在装饰器体中的另一个函数中并返回这个新函数 - 就像那样:

def wrap(func):
    print "before execution ..."
    def inner():
        a = func()
        return a
    print "after execution ..."
    return innner


@wrap
def dosomething():
    print "doing something ..."

答案 1 :(得分:2)

装饰器只是一个可调用函数,它将函数作为参数并返回替换函数。我们将简单地开始,逐步向有用的装饰者发展。

@符号将装饰器应用于函数,因此它等于:

dosomething = wrap(dosomething) 

哪个运行换行。并打印输出。

这里有一些关于装饰器的信息: https://wiki.python.org/moin/PythonDecorators

http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/

答案 2 :(得分:1)

这是装饰者。阅读它here

你到底在做什么: -

def wrap(func):
    print "before execution ..."
    a = func()
    print "after execution ..."
    return a



def dosomething():   # if you remove this decorator symbol
    print "doing something ..."


wrap = wrap(dosomething) # this is what that `@wrap` is doing.
wrap()               

这是两个步骤: -

1: - @wrapdosomething函数的对象传递给wrap函数。

wrap = wrap(dosomething) # passing `dosomething` object to `wrap`

2: - 现在调用wrap函数

wrap()

答案 3 :(得分:1)

执行装饰器代替函数定义。导入模块(或运行它)后,将执行所有顶级语句(类,函数等)。如果你在另一个函数中有你的装饰函数,它内部的装饰器只会在输入函数时执行,如下所示:

def main():
    @wrap
    def dosomething():
       print "doing something ..."

简而言之......你不应该在装饰者中调用你的函数,而是返回一个包装函数,它会做你想要的。

您希望通过以下方式定义装饰器以实现"预期"结果:

def wrap(func):
    def wrapped(*args, **kwargs):
        print "before execution ..."
        func(*args, **kwargs)
        print "after execution ..."
    return wrapped

答案 4 :(得分:1)

Python解释器执行它正在阅读的源文件中的所有代码。

然而,执行def块并不执行包含的代码,它只是创建一个函数对象,这就是为什么你想知道为什么def代码仍在运行。

这里有一个装饰器,翻译成:

dosomething = wrap(dosomething)
dosomething()

运行这些功能。