【问题标题】:Python: How can i decorate function to change it into class methodPython:我如何装饰函数以将其更改为类方法
【发布时间】:2021-04-27 13:59:32
【问题描述】:

我有这样的代码,我想编写装饰器,它将装饰函数添加为类 A 的类方法。

class A:
    pass

@add_class_method(A)
def foo():
    return "Hello!"

@add_instance_method(A)
def bar():
    return "Hello again!"

assert A.foo() == "Hello!"
assert A().bar() == "Hello again!"

【问题讨论】:

  • 你是说@classmethod吗?
  • 作者好像要动态添加一个classmethod
  • 我不这么认为。我想它必须只是类的方法而不是@classmethod

标签: python decorator python-decorators


【解决方案1】:

这种方法怎么样?
附言为了清楚起见,代码没有在结构上进行优化

from functools import wraps


class A:
    pass


def add_class_method(cls):
    def decorator(f):
        @wraps(f)
        def inner(_, *args, **kwargs):
            return f(*args, **kwargs)

        setattr(cls, inner.__name__, classmethod(inner))

        return f

    return decorator


def add_instance_method(cls):
    def decorator(f):
        @wraps(f)
        def inner(_, *args, **kwargs):
            return f(*args, **kwargs)

        setattr(cls, inner.__name__, inner)

        return f

    return decorator


@add_class_method(A)
def foo():
    return "Hello!"


@add_instance_method(A)
def bar():
    return "Hello again!"


assert A.foo() == "Hello!"
assert A().bar() == "Hello again!"

【讨论】:

  • 谢谢
  • This 答案解释得很好
【解决方案2】:

这就是你想要的:

class A:
    def __init__(self):
        pass

    @classmethod
    def foo(cls):
        return "Hello!"

    def bar(self):
        return "Hello again!"


print(A.foo())
print(A().bar())

【讨论】:

  • 不是真的,我必须编写这两个装饰器的代码:add_class_method 和 add_instance_method。此代码只是结果应如何显示的示例。
【解决方案3】:

在此处阅读docs

class MyClass:
    def method(self):
        # instance Method
        return 'instance method called', self

    @classmethod
    def cls_method(cls):
        #Classmethod
        return 'class method called', cls

    @staticmethod
    def static_method():
        # static method
        return 'static method called'

你需要实例化 MyClass 才能到达(调用)实例方法

test = MyClass()
test.method()

您可以直接访问类方法而无需实例化

MyClass.cls_method()
MyClass.static_method()

【讨论】:

  • 但是我的类一开始应该是空的,我必须通过这些装饰器添加方法 foo 和 bar def add_class_method(A): def real_decorator(func): def wrapper(*args,** kwargs): return func(*args, **kwargs) return wrapper() return real_decorator 我已将类传递给装饰器,但我不知道如何使用预期的方法返回它
猜你喜欢
  • 2022-10-18
  • 2011-04-03
  • 2015-06-04
  • 2011-04-13
  • 2015-01-05
  • 2020-02-29
  • 2021-04-16
  • 2012-03-14
  • 2014-09-05
相关资源
最近更新 更多