【问题标题】:Python / How decorating a method part of a class without modifying said class?Python /如何在不修改所述类的情况下装饰类的方法部分?
【发布时间】: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。至少这是这个想法。我猜这就是麻烦所在。我们可以这样装饰一个类的方法吗? (我理解splitstr类的方法)

标签: python decorator


【解决方案1】:

好的,多亏了这个解释才知道:https://www.bogotobogo.com/python/python_differences_between_static_method_and_class_method_instance_method.php

另一种调用方式是通过类名,如下所示:

这是工作代码。

def bla_addition(word):
    def decorator(func):
        def wrapper(*args, **kwargs):

            # Modify `my_list`
            word2 = word + 'bla'
            return  func(word2, *args, **kwargs)
        return wrapper
    return decorator

added = bla_addition('blu')
split = added(str.split)
new_word = split('l')

最佳,

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-14
    • 2012-02-08
    • 2023-02-07
    • 2018-10-22
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    相关资源
    最近更新 更多