如何使用装饰器来修改 *args 的类型?

Posted

技术标签:

【中文标题】如何使用装饰器来修改 *args 的类型?【英文标题】:How can I use a decorator to modify the type of *args? 【发布时间】:2016-10-06 17:42:52 【问题描述】:

我想使用@decorator 让我能够以args 的身份访问' - '.join(args),如下所示。这可能吗,也许使用元类?

def a(*args):
    print(args)
a(1, 2, 3)
# (1, 2, 3)

@magic
def b(*args):
    print(args)
b(1, 2, 3)
# 1 - 2 - 3

【问题讨论】:

【参考方案1】:

你可以靠近:

def magic(func):
    def wrapper(*args):
        return func(' - '.join(map(str, args)))
    return wrapper

但这会打印出('1 - 2 - 3',),因为b 的主体由于*args 而将args 视为一个元组,我怀疑装饰器可以解决这个问题。如果 body 是 print(args[1]) 这样的东西,你期望会发生什么?

【讨论】:

这就是我想要的,但对我来说重要的部分是让 args 成为一个元组。是否可以使用元类来更改此功能? 正文通常不应该索引args - 它会期望它是一个字符串。 (如果是这样,args[1] 将返回字符串中的第二个字符。) 这不是您第一次询问一些非常奇怪的问题。这很可能导致错误和混乱的代码。为什么要这样做? 我正在测试看看是否有效果。它不是一般使用的东西,但包含在我正在设计的一组子类中会很有帮助。我也很好奇这是否可能。 如果您真的想这样做,那么您可能必须修改源代码。考虑 ast 模块。【参考方案2】:

所以问题的一部分是您在需要字符串的地方使用整数,因此将它们转换为字符串,然后使用连接函数。

def magic(func):
    def wrapper(*args):
        return ' - '.join(map(str, args))
    return wrapper

@magic
def a(*args):
    return 'Arguments were .'.format(args)

print(a(1, 2, 3))

【讨论】:

虽然这确实有效,但这不是我想要的。我希望在装饰器中具有该功能,然后能够在函数本身中以字符串 "1 - 2 - 3"(而不是元组)的形式访问 args 这确实有效,但它从未真正执行过a。输出显示1 - 2 - 3,但从不显示Arguments were 1 - 2 - 3。在 magic 装饰器声明中,func() 永远不会被调用。 是的,抱歉,这里的缩进出错了。

以上是关于如何使用装饰器来修改 *args 的类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用@property 装饰器来限制列表中的值

你如何使用 Flask-Login 和自定义 Python 装饰器来分配用户权限?

react——@修饰器——高阶组件的使用——通过装饰器来调用高阶组件——简单修改样式

根据条件应用不同的装饰器

如何创建一个装饰器来装饰生成器函数? [关闭]

Python,如何添加另一个装饰器来过滤现有多装饰器的输出与python中的属性?