Can I replace an existing method of an object in Python?
问:在Python(3.6)中,有没有一种方法可以改变现有对象的方法?(我所说的"方法"是指作为参数传递
例子
假设我有一个类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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! |
如你所见,这个人的反应取决于他们目前的情绪,这种情绪是通过
我可以很容易地创造出一个不在乎金钱、永远快乐的人:
1 2 3 4 5 6 | >>> joe.HasGoodMood = lambda: True >>> joe.SayHi() Hello! >>> joe.Cash = 0 >>> joe.SayHi() Hello! |
酷。注意,python如何知道,在使用
让我们继续我们的例子:如果我想创建一个贪婪的
1 2 3 | >>> greedy_jack = Person() >>> greedy_jack.HasGoodMood = lambda self: self.Cash > 100 TypeError: <lambda>() missing 1 required positional argument: 'self' |
不幸的是,这行不通。有其他方法可以改变方法吗?
免责声明:以上示例仅用于演示目的。我知道我可以使用继承权或保持现金门槛作为
当你在一个类中编写一个
通过在您的实例中分配给
但您已经知道EDOCX1[1]将是什么,因为您要将这个函数分配给一个特定的对象。
1 | greedy_jack.HasGoodMood = (lambda self=greedy_jack: self.Cash > 100) |
这将函数参数
python中的lambda只能是一行。如果需要更长的函数,可以使用
1 2 3 4 | def greedy_jack_HasGoodMood(self=greedy_jack): return self.Cash > 100 greedy_jack.HasGoodMood = greedy_jack_HasGoodMood |
要获得更简单的解决方案,请参阅Andrew McDowell的答案。
使用以下提示:
是否可以在不更改同一类的所有其他实例的情况下更改实例的方法实现?
您可以通过使用类型模块为创建的对象分配一个方法,而不影响类来执行以下操作。您需要这样做,因为函数不会自动接收自对象作为第一个变量,但方法会接收自对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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! |
继承才是出路。
它可以是简单的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Person(object): Cash = 100 def HasGoodMood(self): return self.Cash > 10 def SayHi(self): if self.HasGoodMood(): print('Hello!') else: print('Hmpf.') class newPersonObject(Person): def HasGoodMood(self): return self.Cash > 100 >>> greedy = newClassPerson() >>> greedy.SayHi() hmpf |
当你做
在我看来,更好的选择是在定义对象时接受cash参数。因此,你可以动态地让人们变得贪婪或正常。(未经测试)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Person(object): def __init__(self, cash_to_be_happy): self.cash = cash_to_be_happy def HasGoodMood(self, has_money): return has_money > self.cash def SayHi(self, has_money): if self.HasGoodMood(has_money): print('Hello!') else: print('Hmpf.') >>> joe = Person(100) >>> joe.SayHi(150) Hello! >>> greedy_joe = Person(200) >>> greedy_joe.SayHi(150) Hmpf |