【发布时间】:2020-05-09 22:52:52
【问题描述】:
主要问题
举个例子,说我想装饰str类的split()方法
(这个例子代表了我尝试做的事情,除了我想装饰熊猫DataFrame类的agg方法)。
至少,我得到了同样的错误。
我不喜欢使用 @ 也不喜欢创建 str 类的子类来保持简单(也许这就是它不起作用的原因......)
我遇到了以下问题。
def bla_addition(word):
def decorator(func):
def wrapper(*args, **kwargs):
# Modify `my_list`
word2 = word + 'bla'
return word2.func(*args, **kwargs)
return wrapper
return decorator
added = bla_addition('blu')
split = added(str.split)
new_word = split('l')
遇到错误:AttributeError: 'str' object has no attribute 'func'
请问,你知道我该怎么做吗?
感谢您的帮助和建议。
PS:我在这里使用了没有@的装饰器:
https://www.python-course.eu/python3_decorators.php
我发现避免为split 创建一个新的单行函数非常有帮助。
附带问题
作为一个附带问题,我最初使用此代码。事实证明,不能修改装饰器的参数。我理解正确吗?
def bla_addition(word):
def decorator(func):
def wrapper(*args, **kwargs):
# Modify `my_list`
word += 'bla' #-> parameter word modified
return word.func(*args, **kwargs)
return wrapper
return decorator
added = bla_addition('blu')
split = added(str.split)
new_word = split('l')
产生错误:UnboundLocalError: local variable 'word' referenced before assignment
【问题讨论】:
-
为什么
func会存在于word上? -
请注意,装饰是一个句法概念。
bla_addition只是一个高阶函数(它是一个将函数作为参数或返回函数的函数);装饰是使用@bla_addition def foo():...作为def foo():...; foo = bla_addition(foo)的快捷方式。这里的问题是赋值创建了一个名为word的新局部变量,它隐藏了bla_addition的参数。您可以使用nonlocal关键字来解决此问题,但问题仍然是str值是不可变的。 -
@PeterWood 在这种情况下,
func指向字符串确实存在的函数split。至少这是这个想法。我猜这就是麻烦所在。我们可以这样装饰一个类的方法吗? (我理解split是str类的方法)