python中MethodType的使用解析,转载,修正!

本文深入探讨Python中的MethodType,解释如何使用它将方法绑定到类实例或类本身,包括不同绑定方式对实例属性的影响。同时,文章对比了有无None参数在绑定方法时的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MethodType: 
用MethodType将方法绑定到类,并不是将这个方法直接写到类内部,而是在内存中创建一个link指向外部的方法,在创建实例的时候这个link也会被复制。

情况一:把方法绑定到某个类的实例上

class Student(object):
    pass

def set_name(self, name):
    self.name = name

s1 = Student()
s2 = Student()
s3 = Student()
#将set_name方法绑定到s1实例上
s1.set_name = MethodType(set_name, s1, Student)
s2.set_name = MethodType(set_name, s2, Student)
s1.set_name('tom')
s2.set_name('tony')
>>> print s1.name, ',', s2.name
tom , tony
>>> print s3.name

Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    print s3.name
AttributeError: 'Student' object has no attribute 'name'

解析:MethodType把方法绑定在类实例上时,每个实例有自己单独的指向区域,互不干扰。

情况二: 
(1)将方法绑定在类上(有None参数)

class Student(object):
    pass

def set_name(self, name):
    self.name = name

#将方法绑定在类上(有None参数)
Student.set_name = MethodType(set_name,Student)
s1 = Student()
s2 = Student()
s3 = Student()
s1.set_name('tom')
s2.set_name('tony')
>>> print s1.name, ',', s2.name, ',', s3.name
tom , tony ,

Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    print s1.name, ',', s2.name, ',', s3.name
AttributeError: 'Student' object has no attribute 'name'

解析:MethodType把方法绑定在类上并且有第二个None参数时,这种情况下的表现和情况一类似,通过该类创建的实例会指向各自不同的区域,各个实例之间互不干扰。原博主所指的None是MethodType(set_name,none,student).

(2)将方法绑定在类上(没有None参数)

class Student(object):
    pass

def set_name(self, name):
    self.name = name

#将方法绑定在类上(没有None参数)
Student.set_name = MethodType(set_name,Student)
s1 = Student()
s2 = Student()
s3 = Student()
s1.set_name('tom')
s2.set_name('tony')
>>> print s1.name, ',', s2.name, ',', s3.name
tony , tony , tony

解析:MethodType把方法绑定在类上并且没有第二个None参数时,通过该类创建的实例都会指向相同的区域,导致后面实例的值会覆盖前面实例的值。

 

#1、python支持动态给类和实例增加属性和方法;

#2、python slots只能限制实例的属性及方法,对于类则没有影响,对于子类则更是没有限制。

#3.将方法绑定给类后,类调用方法后,类和实例都可以访问类中的属性与方法,这不受slots范围限制

#方法没有绑定给类而直接绑定给实例时,需要在slots规定范围中加入该方法和方法中的属性 class Student(object): slots = ('name','age','set_age')#用slots限制类的实例的属性 pass s = Student()

动态给实例增加属性

s.name = 'Michael' print(s.name)

动态给类增加属性不受限制

Student.gender = 'male' print(Student.gender) print(s.gender)

动态给类增加方法和属性

def set_score(self, score):#如果在slots中没有属性score将报lotsAttributeError: 'Student' object has no attribute 'score' self.score = score Student.set_score = set_score#给类绑定方法和属性不受限制,可以不在slots中加set_score和score Student.set_score(Student,66)#类调用set_acore方法给自己绑定属性score为66 print(Student.score) print(s.score)#实例可以调用类属性scored但是不能用s.set_score(89)来中心赋值

动态给实例增加方法和属性

def set_age(self, age): self.age = age

from types import MethodType s.set_age = MethodType(set_age, s)#直接给实例绑定方法由于类中没有该方法,必须在slots中添加set_age, age才可以 s.set_age(25) print(s.age)

动态给类增加方法和属性

Student.set_age=set_age#给类绑定方法和属性不受限制,可以不在slots中加set_score和score s.set_age(26)#但是由于Student类没有调用set__age方法,所以类中没有age的值。实例调用该方法赋值就必须在slots中加上age属性了 print(s.age)

这种情况下其实最好是能够看一下MethodType类实现的源代码,了解三个参数都是什么作用,这样能够更深刻的理解,但我暂时还没找到源代码,有机会看到再来补充一哈。

以上内容从网上转发,侵权删帖!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值