Python类与实例属性及方法绑定详解
本文深入解析Python中类与实例的属性及方法绑定机制。详细阐述类属性的定义与访问,实例属性对类属性的覆盖与删除后的回退逻辑。重点讲解通过self或直接赋值绑定实例属性,以及使用MethodType为类或特定实例绑定方法的差异,特别是共享引用导致的副作用分析。
前言
在Python类与实例的方法调用中,许多初学者可能会感到困惑。经过深入思考,我将自己的理解整理如下,旨在加深自身对这门抽象语言的理解,同时帮助希望学习Python的朋友理清思路。由于Python属于动态语言,类和根据类创建的实例都可以动态地绑定任意属性和方法。接下来将分别介绍这些绑定机制。
1. 类绑定属性
类属性可以直接在class定义中声明,这类属性属于类本身。
class Student(object): name = 'Student'
尽管该属性归属于类,但该类的所有实例均可访问它。
class Student(object): name = 'Student' s = Student() # 创建实例s print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性 print(Student.name) # 打印类的name属性 Student Student
此时,如果修改实例s的name属性值,结果如下:
s.name = 'xiaoming' # 给实例绑定name属性 print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性 print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问 xiaoming Student
接下来,删除实例s的name属性:
del s.name # 如果删除实例的name属性 print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了 Student
由此可见,同名实例属性会覆盖类属性;当删除实例属性后,实例将向上查找并访问到类属性。
2. 实例绑定属性
实例绑定属性主要有两种方式:一是通过类的self变量进行绑定,二是直接对实例进行赋值。
class Student(object):
def __init__(self, name):
self.name = name
s = Student('Bob')#方法一 通过类的self变量绑定属性
s.score = 90#方法二 直接赋值
3. 类绑定方法
类绑定方法分为两种情况。第一种类似于类绑定属性,示例代码如下:
Class Student(object): pass a=Student()#创建实例 def set_score(self,score): self.score=score Student.set_score=set_score#类绑定方法 a.set_score(99)#调用方法 a.score 99#输出
第二种方法是使用MethodType给类绑定方法:
Class Student(object): pass a=Student()#创建实例 def set_score(self,score): self.score=score from types import MethodType Student.set_score = MethodType(set_score, Student) a.set_score(99)#调用方法 a.score 99#输出
这种方法有一个需要注意的细节,如果继续创建另一个实例b:
b=Student() b.set_score(60) b.score a.score 60
会发现实例a的score值也变成了60。个人理解是,这里的score并非像前一种方法那样直接绑定在类上,而是类似于列表那样的共享引用关系。
即实例a和b都引用同一个score作为自己的属性,当该属性被修改时,所有引用它的实例对应的属性都会同步发生变化。
4. 实例绑定方法
第一种方式是通过给类绑定方法,使得所有实例均可调用,如上所示。
第二种方式是使用MethodType给单个实例绑定方法。
Class Student(object): pass a=Student()#创建实例 def set_score(self,score): self.score=score from types import MethodType a.set_score = MethodType(set_score, a) a.set_score(99)#调用方法 a.score 99#输出
注意这种方式仅对实例a生效。如果需要让Student类的所有实例都能调用该方法,则应直接给类Student绑定方法即可。
总结
以上就是本文的全部内容,希望本文的内容对大家的学习或工作能有所帮助。如有任何疑问,欢迎留言交流,感谢大家对本站的支持。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













