>>> class C: # 类C在定义的时候是一个类,在写完定义后就是一个类对象,因为Python无处不对象,就连方法也是一个对象
count = 0
>>> a = C()
>>> b = C()
>>> a.count
0
>>> b.count
0
>>> b.count += 10 #对b.count赋值的时候生成一个count覆盖了类对象C的count
>>> a.count
0
>>> b.count
10
>>> C.count
0
>>> C.count += 100
>>> a.count
100
>>> b.count #前方高能
10
属性的名字和方法名相同,属性会覆盖方法。
>>> class C:
def x(self):
print("lalala")
>>> c = C()
>>> c.x()
lalala
>>> c.x = 1 #对实例对象c创建了一个x属性
>>> c.x
1
>>> c.x()
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
c.x()
TypeError: 'int' object is not callable
为了避免这种情况,我们应该遵循如下约定:
①不要试图在一个类里面定义出所有能想到的特性和方法,应该利用继承和组合机制来进行扩展。
②用不同的词性命名,如属性名用名词,方法名用动词。
绑定:Python严格要求方法需要有实例才能被调用,这种限制其实就是Python所谓的绑定概念。
如果没有绑定:
>>> class A:
def printA(): #错误示范:没有绑定
print('A')
>>> a = A()
>>> a.printA() #调用该方法的时候,a会把自身作为一个参数传入
Traceback (most recent call last):
File "<pyshell#33>", line 1, in <module>
a.printA()
TypeError: printA() takes 0 positional arguments but 1 was given #因此需要self接受绑定
深入理解:
>>> class C:
def setXY(self, x, y):
self.x = x
self.y = y
def printXY(self):
print(self.x, self.y)
>>> d = C() #实例化对象叫d,类对象和类均叫C
>>> d.__dict__ #__dic__用来查看对象包含的属性
{} #显示的是一个字典,该字典中仅有实例对象的属性,不显示类属性和特殊属性
>>> C.__dict__
mappingproxy({'__module__': '__main__', 'setXY': <function C.setXY at 0x00000000032D7BF8>, 'printXY': <function C.printXY at 0x00000000032D7C80>, '__dict__': <attribute '__dict__' of 'C' objects>, '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None}) #键表示属性名,值表示属性对应的值
#对象C拥有printXY 和 setXY方法,但实例对象d没拥有是因为这两个是静态的绑定在类对象里面的
>>> d.setXY(4, 5)
>>> d.__dict__
{'x': 4, 'y': 5} #这两个属性仅属于d对象
>>> C.__dict__ #原因归因于参数self,d调用方法时传入自身,self也赋值为d,也就是d.x = 4, d.y = 5,所以4和5最后存放进去的是实例对象d的空间,因此这两个属性只属于实例对象d
mappingproxy({'__module__': '__main__', 'setXY': <function C.setXY at 0x00000000032D7BF8>, 'printXY': <function C.printXY at 0x00000000032D7C80>, '__dict__': <attribute '__dict__' of 'C' objects>, '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None})
>>> del C
>>> e = C() #显然,删除掉类对象后,再实例化该类对象是不行的
Traceback (most recent call last):
File "<pyshell#59>", line 1, in <module>
e = C()
NameError: name 'C' is not defined
>>> d.printXY() #但实例化对象d还存在,探讨d在类对象被删除的情况下还能不能调用方法
4 5 #答案是可以的,因为类中定义的属性和方法是静态的,就算类对象被删除了,他们依然存放在内存当中