如何为Fabric任务添加自定义装饰器

6

首先,我必须承认我对Fabric和Python都很新手,但我希望按照正确的方式进行操作,所以……我想用一个prepare函数来装饰我的一些任务,在已有的变量基础上向env中添加一些变量。看一下:

from fabric.api import *
import fabstork.project.base as base
import fabstork.utils.drupal as utils

def prepare(task):
    """ Decorator to set some additional environment variables """
    def prepared(*args, **kwargs):
        env.sites_folder = env.sites_folder if 'sites_folder' in env else 'default'
        env.settings_file = "%s/www/sites/%s/settings.php" % (env.build_path, env.sites_folder)
        # more to come
        return task(*args, **kwargs)

    return prepared


@task
@prepare
def push(ref='HEAD'):
    """
    Deploy a commit to a host
    """
    base.push(ref)
    utils.settings_php()
    utils.link_files()
    utils.set_perms()

上面的例子失败了,因为push不再是任务了。当在命令行执行fab --list时,它不在可用任务列表中。省略装饰器会得到一个完美的任务。我做错了什么?
1个回答

9
from fabric.decorators import task
from functools import wraps

def custom_decorator(func):
    @wraps(func)
    def decorated(*args, **kwargs):
        print "this function is decorated."
        return func(*args, **kwargs)
    return decorated

@task
@custom_decorator
def some_function():
    print "this is function"

结果:

# fab -l
>Available commands:
>
>    some_function

# fab some_function
>this function is decorated.
>this is function
>
>Done.

1
谢谢!所以我基本上错过了 **@wraps(func)**。你能否更新你的答案并明确指出这一点? - Knörpeltäng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接