在 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.