【问题标题】:Python Decorator Object Not Being AvailablePython 装饰器对象不可用
【发布时间】:2014-06-25 16:20:57
【问题描述】:

我明白了

NameError: global name 'git' is not defined

git.add(log_filename)。我不明白为什么repo = Repo(ABSOLUTE_PATH)git = repo.gitoriginal_function = function(ABSOLUTE_PATH, GIT_WORKING_DIR, log_name, remove_logs) 之前被调用。 git 对象不应该对被调用函数可用吗?

我想在这种情况下使用装饰器,因为一个单独的函数将使用类似的功能。我怎样才能使这个装饰器工作?

 def raw_git(function):
    @wraps(function)
    def wrapper(ABSOLUTE_PATH, GIT_WORKING_DIR,
            log_name=None, remove_logs=None):
        try:
            repo = Repo(ABSOLUTE_PATH)
            git = repo.git
        except NoSuchPathError:
            raise Exception("Error in finding local git path!")
        original_function = function(ABSOLUTE_PATH, GIT_WORKING_DIR,
                log_name, remove_logs)
        return original_function
    return wrapper


@raw_git
def git_add_log(ABSOLUTE_PATH, GIT_WORKING_DIR,
        log_name=None, remove_logs=None):
    log_name = GIT_WORKING_DIR + "/" + log_name
    try:
        git.add(log_filename)
        git.commit(message="Removing oldest logs")
        git.push()
    except GitCommandError:
        raise Exception("There was an error with git command "
                "for removing oldest log(s)")

【问题讨论】:

    标签: python decorator python-decorators


    【解决方案1】:

    git 是包装函数内的 local 名称。它在该命名空间之外不可见,因此在 git_add_log 中不可见。

    给该函数一个 git 参数,并在调用包装函数时传入对象:

    def raw_git(function):
        @wraps(function)
        def wrapper(ABSOLUTE_PATH, GIT_WORKING_DIR,
                log_name=None, remove_logs=None):
            try:
                repo = Repo(ABSOLUTE_PATH)
                git = repo.git
            except NoSuchPathError:
                raise Exception("Error in finding local git path!")
            original_function = function(git, ABSOLUTE_PATH, GIT_WORKING_DIR,
                    log_name, remove_logs)
            return original_function
        return wrapper
    
    
    @raw_git
    def git_add_log(git, ABSOLUTE_PATH, GIT_WORKING_DIR,
            log_name=None, remove_logs=None):
        log_name = GIT_WORKING_DIR + "/" + log_name
        try:
            git.add(log_filename)
            git.commit(message="Removing oldest logs")
            git.push()
        except GitCommandError:
            raise Exception("There was an error with git command "
                    "for removing oldest log(s)")
    

    【讨论】:

    • 我明白了……在这种情况下,我还需要装饰器吗?我可以创建一个单独的函数并返回那个 git 对象。
    • @dman:你不需要 装饰器,但如果你有很多需要 git 的函数,它仍然是一个有用的模式目的。但是一个单独的函数会使函数签名对于局外人更容易理解。
    猜你喜欢
    • 2022-01-03
    • 2021-11-22
    • 2019-11-18
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 2012-06-07
    • 2020-08-19
    • 1970-01-01
    相关资源
    最近更新 更多