Python进阶(面向对象编程基础)(三)
6、类属性和实例属性名字冲突怎么办
修改类属性会导致所有实例访问到的类属性全部都受影响,但是,如果在实例变量上修改类属性会发生什么问题呢?
1 class Person(object): 2 address = 'Earth' 3 def __init__(self, name): 4 self.name = name 5 6 p1 = Person('Bob') 7 p2 = Person('Alice') 8 9 print 'Person.address = ' + Person.address 10 11 p1.address = 'China' 12 print 'p1.address = ' + p1.address 13 14 print 'Person.address = ' + Person.address 15 print 'p2.address = ' + p2.address
Person.address = Earth p1.address = China Person.address = Earth p2.address = Earth
当实例属性和类属性重名时,实例属性优先级高,它将屏蔽掉对类属性的访问。千万不要在实例上修改类属性,它实际上并没有修改类属性,而是给实例绑定了一个实例属性。
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 __author__ = 'ziv·chan' 4 5 #把上节的 Person 类属性 count 改为 __count, 6 #再试试能否从实例和类访问该属性。 7 class Person(object): 8 __count = 0 9 def __init__(self): 10 Person.__count += 1 11 print Person.__count 12 13 14 try: 15 p1 = Person() 16 p2 = Person() 17 18 print Person.__count 19 print p1.__count 20 except AttributeError: 21 print 'attributeerror'
1 2 attributeerror
一个实例的私有属性就是以__开头的属性,无法被外部访问,那这些属性定义有什么用?
虽然私有属性无法从外部访问,但是,从类的内部是可以访问的(如上)。除了可以定义实例的属性外,还可以定义实例的方法。
实例的方法就是在类中定义的函数,它的第一个参数永远是 self,指向调用该方法的实例本身,其他参数和一个普通函数是完全一样的:
class Person(object): def __init__(self, name): self.__name = name def get_name(self): return self.__name
调用实例方法必须在实例上调用:
p1 = Person('Bob') print p1.get_name() # self不需要显式传入 # => Bob
在实例方法内部,可以访问所有实例属性,这样,如果外部需要访问私有属性,可以通过方法调用获得,这种数据封装的形式除了能保护内部数据一致性外,还可以简化外部调用的难度。
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 __author__ = 'ziv·chan' 4 5 # 给 Person 类增加一个私有属性 __score,表示分数,再增加一个实例方法 get_grade(), 6 # 能根据 __score 的值分别返回 A-优秀, B-及格, C-不及格三档。 7 8 class Person(object): 9 10 def __init__(self,score): 11 self.__score = score 12 13 def get_grade(self): 14 if self.__score >= 80: 15 return 'A' 16 elif self.__score <60: 17 return 'C' 18 else: 19 return 'B' 20 21 p1 = Person(90) 22 p2 = Person(65) 23 p3 = Person(80) 24 print p1.get_grade() 25 print p2.get_grade() 26 print p3.get_grade()
结果就不贴了..
专注于技术,专注于生活