类的属性和实例的属性

 

由于 Python 是动态语言,根据类创建的实例,可以任意绑定属性。给实例绑定属性的方法可以通过实例变量,或者通过 self 变量来实现的,比如下面我们创建一个Student类:

 

attr.py:

 

 

[python] view plain copy
  1. #!/usr/bin/env Python3  
  2. # -*- encoding:UTF-8 -*-  
  3.   
  4. class Student(object):  
  5.     def __init__(self,name):  
  6.         self.name = name  
  7. s = Student('Appleyk')  
  8. print(s.name)  
  9. s.score = 90  
  10. print(s.score)  

 

 

上述demo,我们给Student类创建了一个实例属性,self.name,同时,我们用s.score=90绑定变量的的方式给实例s又添加了一个score属性,我们看下打印结果:

 

 

上面说了,name和score都是类Student的实例s的属性,那么,我们的Student类能不能直接访问实例s的两个属性呢?我们看下:

 

 

首先我们的IDE已经给我们答案了,智能提示下拉列表里并没有找到任何属于类Student的属性,我们再看下执行结果:

 


没有发现类Student的属性name,我们用hasattr(getattr)函数证明一下:

 

 

如果我们想给Student也分配一个属性怎么办,和给实例绑定属性一样,只不过类的不用self指定(self指定的属于类的实例),而是直接在类的内部创建一个变量或者在类外直接通过绑定变量的方式实现:

 

 

[python] view plain copy
  1. #!/usr/bin/env Python3  
  2. # -*- encoding:UTF-8 -*-  
  3.   
  4. class Student(object):  
  5.     name = 'Student'         #给类Student也创建一个属性变量name  
  6.     def __init__(self,name): #实例的属性变量name    
  7.         self.name = name  
  8. s = Student('Appleyk')  
  9. print(s.name)  
  10. print(Student.name)  


我们给Student类的实例s创建了一个属性name,同样,我们给我们的类Student也绑定了一个属性name,当然这两个name属性名一样,但是我们实际操作的时候,值我们给的不一样,以示区别,看下执行结果:

 

 

上面输出结果可以看出,虽然都是访问的name,但是类和实例各自访问各自的属性变量name;我们再给类Student绑定一个属性score,然后我们拿实例s访问一下,看看能不能访问到类Student新添加的属性score:

 

 

 

如果上面,还没有说服力的话(实例可以访问类的属性),我们再看下面一个例子,我们知道,如果我们直接用s.name的话,访问的是实例的属性:

 

 

如果,我们用del语句删除掉实例s的属性name的话,s.name还存在吗,如果存在的话,这个name的主子是谁?我们看下下面的测试:

 

 

有人可能这样问,既然我们说了,实例可以访问类的属性,那么,如果,类的属性和实例的属性同名的话,我们用实例访问name,怎么知道,s访问的这个name到底是先输出'Appleyk'还是'Student'呢,由于实例属性优先级比类属性高,因此,它会屏蔽掉类Student的name 属性,所以,我们在s.name的时候,先输出实例属性对应的值!

 

 

结束语:Python的动态语言使得我们写代码的时候很随心所欲,但是,我们越往后深入,我们会发现,要想很好的理解和掌握这种动态语言的灵活性,不花点时间去消化,根本吃不透,所以,学习不光需要技巧和方法,重要的是要有耐心!