>>> class C:...     count = 0...>>> a = C()>>> b = C()>>> c = C()>>> print(a.count,b.count,c.count)0 0 0>>> c.count +=100>>> print(a.count,b.count,c.count)0 0 100>>> C.count +=100>>> print(a.count,b.count,c.count)100 100 100

上面可以看出,对实例对象c的count的属性进行赋值后,就相当于覆盖了类对象C的count属性。如果没有赋值覆盖,那么引用的是类对象的count属性。

有点绕对吧

看一下图就很好理解了

类,类对象和实例对象(第十四章)_java

注意;类中定义的属性是静态变量,也就是相当于C语言中加上static声明的变量,类的属性食欲类对象进行绑定,并不会以来任何他的实例对象。

如果属性跟方法名相同,属性会覆盖方法


>>> class C:...     def x(self):...             print("xman")#如果属性跟方法名相同,属性会覆盖方法...
>>> c = C()
>>> c.x()xman
>>> c.x = 1#覆盖
>>> c.x()Traceback (most recent call last):  File ", line 1, in <module>TypeError: 'int' object is not callable
>>> c.x#覆盖后属性为1 ,也即是变量会覆盖函数1>>>

规则

  • 类的定义要少吃多餐,不要试图在一个类里边定义出所有能想到的特性和方法,应该利用继承和组合机制来进行扩展

  • 用不同的词性,如属性(变量)用名词,方法(函数)用动词,都采用

驼命名法


printEmployeePaychecks();print_employee_paychecks();

第一个函数名使用了骆驼式命名法——函数名中的每一个逻辑断点都有一个大写字母来标记;

第二个函数名使用了下划线法----函数名中的每一个逻辑断点都有一个下划线来标记。

什么是绑定


>>> class CC:...     def setXY(self,x,y):...             self.x = x...             self.y = y...     def printXY(self):...             print(self.x,self.y)...>>> dd = CC()>>> dd.setXY(2,4)>>> dd.printXY()2 4>>>

可以使用__dict__查看对象的的所有属性


>>> class CC:...     def setXY(self,x,y):...             self.x = x...             self.y = y...     def printXY(self):...             print(self.x,self.y)...>>> dd = CC()>>> dd.setXY(2,4)>>> dd.printXY<bound method CC.printXY of >>>> dd.printXY()2 4>>> dd.__dict__{'y': 4, 'x': 2}>>> CC.__dict__mappingproxy({'printXY': , '__dict__': , '__weakref__': , '__doc__': None, 'setXY': , '__module__': '__main__'})>>>

__dict__属性是由一个字典组成,字典中仅有得实例对象的属性,不显示类属性和特殊属性,键表示属性名,值表示对键对应的


>>> dd.printXY()2 4>>> dd.__dict__{'y': 4, 'x': 2}

兑现实例对象dd有了两个新属性,而是这两个属性是仅属于实例对象的


>>> CC.__dict__mappingproxy({'printXY': , '__dict__': , '__weakref__': , '__doc__': None, 'setXY': , '__module__': '__main__'})

这完全归功于self参数,当时离对象dd去调用setXY方法的时候,他传入的第一个参数就是dd,那么self.x=2,self.y=4.也就相当于dd.x=2,dd.y=4所以你在实例对象,甚至类对象中都看不到xy因为这两个属性只属于实例对象dd的

如果删除类对象,还是可以使用dd来调用printXY方法