Q:有没有办法改变Python(3.6)中现有对象的方法?(我所说的"方法"是指作为参数传递self的函数.)


Example

比如说,我有一个Person班,有一些非常有用的方法SayHi():

class Person(object):
    Cash = 100
    def HasGoodMood(self):
        return self.Cash > 10

    def SayHi(self):
        if self.HasGoodMood():
            print('Hello!')
        else:
            print('Hmpf.')

>>> joe = Person()
>>> joe.SayHi()
Hello!

正如你所看到的,这个人的react 取决于他们当前的情绪,这个情绪是通过方法HasGoodMood()计算出来的.当一个违约的人身上有超过10美元的现金时,他就会有好心情.

我可以很容易地创造出一个不在乎金钱、一直快乐的人:

>>> joe.HasGoodMood = lambda: True
>>> joe.SayHi()
Hello!
>>> joe.Cash = 0
>>> joe.SayHi()
Hello!

凉的请注意,Python如何知道,当使用HasGoodMood的原始实现时,它会以静默方式传递self作为第一个参数,但如果我将其更改为lambda: True,它将调用不带参数的函数.问题是:如果我想为另一个也接受self作为参数的函数更改默认值HasGoodMood,该怎么办?

让我们继续我们的例子:如果我想创造一个贪婪的Person人,只有当他们身上有超过Person美元的钱时,他们才会快乐,那该怎么办?我想做一些类似的事情:

>>> greedy_jack = Person()
>>> greedy_jack.HasGoodMood = lambda self: self.Cash > 100
TypeError: <lambda>() missing 1 required positional argument: 'self'

不幸的是,这不起作用.还有其他方法可以改变方法吗?


Disclaimer:上述示例仅用于演示目的.我知道我可以使用继承权或保留现金门槛作为Person人的财产.但这不是问题的重点.

推荐答案

使用以下提示:

Is it possible to change an instance's method implementation without changing all other instances of the same class?

在不影响使用以下方法创建的对象的情况下,可以将类型分配给以下模块.之所以需要这样做,是因为函数不会自动接收self对象作为第一个变量,但方法会.

import types

joe = Person()
bob = Person()

joe.SayHi()
>>> Hello!

def greedy_has_good_mood(self):
    return self.Cash > 100

joe.HasGoodMood = types.MethodType(greedy_has_good_mood, joe)


joe.SayHi()
>>> Hmpf.
bob.SayHi()

>>> Hello!

Python-3.x相关问答推荐

为什么打印语句在Python多处理脚本中执行两次?

十进制浮点数到整型的转换错误

regexp多重前瞻行为的解释

与 pandas 0.22 相比,pandas 2.0.3 中的 df.replace() 会抛出 ValueError 错误

根据按不同列中的值分组的平均值划分 DataFrame

在 string.find() 条件下加入两个 Dataframes

在 groupby 之后,Pandas 在特定类别中获得最常见和最后的值

有没有办法使用重采样矢量化添加缺失的月份?

合并问卷中多列中的稀疏问题 - Pandas

Python pandas将单元格值移动到同一行中的另一个单元格

列表中的重复数字与列表理解

spinbutton调整up/down箭头

TypeError:JSON 对象必须是 str,而不是 'dict'

Python中调用者函数的访问变量

如何将numpy数组图像转换为字节?

计数大于Pandas groupby 中的值的项目

从 csv 中删除单行而不复制文件

Python 2 与 Python 3 - urllib 格式

什么是ANSI_X3.4-1968编码?

在 Meta 中创建具有动态模型的通用序列化程序