python - 如何在 Python 中动态添加一个类方法

标签 python python-3.x lazy-evaluation class-method

我正在使用 Python 3。 我知道 @classmethod 装饰器。另外,我知道类方法可以从实例中调用。

class HappyClass(object):
    @classmethod
    def say_hello():
        print('hello')
HappyClass.say_hello() # hello
HappyClass().say_hello() # hello

但是,我似乎无法动态创建类方法并让它们从实例中调用。假设我想要类似的东西

class SadClass(object):
    def __init__(self, *args, **kwargs):
        # create a class method say_dynamic

SadClass.say_dynamic() # prints "dynamic!"
SadClass().say_dynamic() # prints "dynamic!"

我玩过 cls.__dict__(它会产生异常),还有 setattr(cls, 'say_dynamic', blahblah)(它只会让事情变得可调用来自类而不是实例)。

如果你问我为什么,我想做一个惰性类属性。但它不能从实例中调用。

@classmethod
def search_url(cls):
    if  hasattr(cls, '_search_url'):
        setattr(cls, '_search_url', reverse('%s-search' % cls._meta.model_name))
    return cls._search_url

可能是因为还没有从类中调用该属性...

综上所述,我想添加一个惰性可以从实例中调用的方法...这可以实现吗以一种优雅的(nottoomanylines)方式?

有什么想法吗?

我是如何做到的

对不起,我的例子很糟糕:\

反正我最后是这样的...

@classmethod
def search_url(cls):
    if not hasattr(cls, '_search_url'):
        setattr(cls, '_search_url', reverse('%s-search' % cls._meta.model_name))
    return cls._search_url

setattr 确实有效,但我在测试时犯了一个错误...

最佳答案

您可以随时向类添加函数,这种做法称为猴子修补:

class SadClass:
    pass

@classmethod
def say_dynamic(cls):
    print('hello')
SadClass.say_dynamic = say_dynamic

>>> SadClass.say_dynamic()
hello
>>> SadClass().say_dynamic()
hello

请注意,您正在使用 classmethod 装饰器,但您的函数不接受任何参数,这表明它被设计为一个静态 方法。您是想改用 staticmethod 吗?

关于python - 如何在 Python 中动态添加一个类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24538855/

相关文章:

python - 如何在不使用selenium等 headless 浏览器的情况下登录morningstar.com?

python-3.x - 使用 openCV 过滤掉特定颜色的所有内容

list - 递归函数的惰性模式

python - 进程运行时如何在进程之间进行通信

python - 如何删除列表中的空格?

Scala 惰性集合增长

haskell - 如何在 Haskell 中强制立即调用函数?

python "Stars and Bars"

python - HTTP 错误 422 : Unprocessable Entity - when calling API from Python (but curl works)

python - 获取 Selenium 的搜索栏 ID