在 Python 中向现有对象实例添加方法

在 Python 中向现有对象实例添加方法

Add a method to an existing object instance in Python

使用该types.MethodType函数将方法添加到现有对象实例,例如
my_inst.increase_salary = types.MethodType(increase_salary, my_inst).
MethodType函数会将方法绑定到实例。

主程序
import types class Employee(): def __init__(self, name, salary): self.name = name self.salary = salary alice = Employee('Alice', 100) def increase_salary(self): self.salary += 100 return self.salary alice.increase_salary = types.MethodType(increase_salary, alice) print(alice.increase_salary()) # 👉️ 200 print(alice.increase_salary()) # 👉️ 300

向现有对象添加方法时,我们必须注意将其绑定到对象,以便在调用方法时将实例作为第一个参数传递

主程序
class Employee(): def __init__(self, name, salary): self.name = name self.salary = salary alice = Employee('Alice', 100) def increase_salary(self): self.salary += 100 return self.salary print(increase_salary) # <function increase_salary at 0x7f6b939ffd90> print(alice.__init__) # <bound method Employee.__init__ of <__main__.Employee object at 0x7f6b938f7100>>

然而,如果我们在类上添加方法,我们就不必关心绑定它,它将是一个未绑定的方法,可用于所有先前创建的实例。

主程序
class Employee(): def __init__(self, name, salary): self.name = name self.salary = salary alice = Employee('Alice', 100) bob = Employee('Bob', 100) def increase_salary(self): self.salary += 100 return self.salary Employee.increase_salary = increase_salary print(Employee.increase_salary) # <function increase_salary at 0x7fb813bf7d90> print(alice.increase_salary()) # 👉️ 200 print(bob.increase_salary()) # 👉️ 200

When the method is added directly on the existing object instance, it is only
available on the specific instance.

main.py
import types class Employee(): def __init__(self, name, salary): self.name = name self.salary = salary alice = Employee('Alice', 100) bob = Employee('Bob', 100) def increase_salary(self): self.salary += 100 return self.salary alice.increase_salary = types.MethodType(increase_salary, alice) # <bound method increase_salary of <__main__.Employee object at 0x7f6edb29f4c0>> print(alice.increase_salary) print(alice.increase_salary()) # 👉️ 200 # ⛔️ AttributeError: 'Employee' object has no attribute 'increase_salary' print(bob.increase_salary())

An alternative to using the MethodType function is to use a descriptor to bind
the method to the class instance.

main.py
class Employee(): def __init__(self, name, salary): self.name = name self.salary = salary alice = Employee('Alice', 100) bob = Employee('Bob', 100) def increase_salary(self): self.salary += 100 return self.salary alice.increase_salary = increase_salary.__get__(alice) print(alice.increase_salary()) # 👉️ 200 print(alice.increase_salary()) # 👉️ 300 # <bound method increase_salary of <__main__.Employee object at 0x7f31cc8174c0>> print(increase_salary.__get__(alice))

We used the
__get__()
method on the function.

Functions have a __get__() method so they can be converted to a method when accessed as attributes.

This helps us convert the increase_salary function to a method that is bound
to the specific class instance.