【问题标题】:Python: How to pass variables into decorators AND decorators pass decorator variables back into function as well?Python:如何将变量传递给装饰器并且装饰器也将装饰器变量传递回函数?
【发布时间】:2020-12-18 07:32:10
【问题描述】:

我总是循环浏览目录的文件来执行各种数据操作。 因此,我总是使用以下代码

for subdir, dirs, files in os.walk(dir_):
    for file_name in files:
        # manipulations here

我没有继续为每个函数编写这些代码行,而是想知道是否可以通过使用装饰器使其变得更好。像下面这样:

# decorator
def wrapper_layer1(directory):
    def wrapper_layer2(func):
        def wrapper_layer3(*args, **kwargs):
            for subdir, dirs, files in os.walk(dir_):
                for file_name in files:
                    func(subdir, dirs, files, file_name)
            return wrapper_layer3
        return wrapper_layer2
    return wrapper_layer1

# function
@wrapper_layer1(dir_=r"")
def func(subdir, dirs, files, file_name):
    # manipulations here

我发现很多资源都集中在如何将参数传递给装饰器。 但是在这种情况下,它不仅需要将参数传递给装饰器,还需要装饰器将参数传递给函数。

有人知道怎么实现吗?

【问题讨论】:

  • 这有什么问题?
  • 第二段代码演示了我想要做什么,但实际上它不起作用大声笑
  • 它有什么作用?你有错误吗?
  • 它运行没有任何错误,但也没有输出。所以我不确定如何使它工作
  • 好吧,你永远不会打电话给func,所以你没有得到任何输出。

标签: python decorator


【解决方案1】:

接受装饰器函数参数的函数(在您的示例中为wrapper_layer1)应该返回装饰器函数,而不是自身。同样,装饰器函数(在您的示例中为wrapper_layer2)应该返回包装函数,而不是它本身。最后,包装函数(在您的示例中为wrapper_layer3)应该将自身以外的其他内容返回给调用者,如果有的话:

def for_each_file(dir_):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for subdir, dirs, files in os.walk(dir_):
                for file_name in files:
                    func(subdir, dirs, files, file_name)
            # return something meaningful, or don't return anything at all if
            # the caller does not expect a returning value
        return wrapper
    return decorator

【讨论】:

    【解决方案2】:

    我犯了一些错误,现在可以了。 谢谢大家指出我的错误。

    这对我有用。

    # decorator
    def wrapper_layer1(directory):
        def wrapper_layer2(func):
            def wrapper_layer3(*args, **kwargs):
                for subdir, dirs, files in os.walk(directory):
                    for file_name in files:
                        func(subdir, dirs, files, file_name)
            return wrapper_layer3
        return wrapper_layer2
    
    # function
    @wrapper_layer1(directory=dir_)
    def func(subdir, dirs, files, file_name):
        print(subdir)
        print(dirs)
        print(files)
        print(file_name)
    
    
    func(dir_)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-20
      • 2018-09-11
      • 2012-12-13
      • 2010-12-30
      • 2021-11-21
      • 2021-11-15
      • 2021-08-22
      • 2020-01-05
      相关资源
      最近更新 更多