分析一段代码:
>>>class C:
count = 0
>>>a = C()
>>>b = C()
>>>c = C()
>>>print(a.count,b.count,c.count)
0 0 0
>>>c.count += 10
>>>print(a.count,b.count,c.count)
0 0 10
>>>C.count += 100
>>>print(a.count,b.count,c.count)
100 100 10
可见对实例对象c的count属性赋值,相当于覆盖类对象C的count属性,若没有赋值覆盖,则引用的是类对象的count属性
类中定义的属性是静态变量(C语言中static关键字声明的变量),类的属性与类对象绑定,不依赖于任何实例对象。
若属性名和方法名相同,则属性覆盖方法
class C:
def x(self):
print('haha')
>>>c.x()
haha
>>>c.x = 1
>>>c.x
1
>>>c.x() #error
注意点:
1)类的定义要少吃多餐,通过继承和组合来逐步定义类的全部属性和方法。
2)用不同词性命名,如方法用动词,属性用名词,可使用骆驼命名法。
绑定
Python要求方法有实例才能被调用,该限制即绑定
>>>class BB:
def printBB():
print("go")
>>>BB.printBB()
go
以上使用方法产生问题:根据该类实例化的对象无法调用函数,如下:
>>>bb = BB()
>>>bb.printBB()
#TypeError
这是由于Python绑定机制,自动把bb对象作为第一个参数传入,出现TypeError
>>>class CC:
def setXY(self,x,y):
self.x = x
self.y = y
def printXY(self):
print(self.x,self.y)
>>>dd = CC()
使用_ _dict_ _查看对象属性
>>>dd.setXY(4,5)
>>>dd._ _dict_ _
{'x':4,'y':5}
表示实例对象dd有两个新属性,且仅属于实例对象(因为self参数的影响,self.x=dd.x,所以在其他实例对象或类对象中看不到x,y,只属于实例对象dd)
若删除类实例,则dd仍然能调用方法,如下
>>>del CC
>>>dd.printXY()
4 5
类与对象的相关BIF
1.issubclass(class A,classinfo B)
若A是B的子类,则返回true,否则false
1)一个类是其自身的子类
2)B可以是类对象组成的元组,A只要是元组中任何一类的子类即可返回true
3)其他情况,抛出TypeError
>>>class A:
pass
>>>class B(A):
pass
>>>issubclass(B,A)
True
>>>issubclass(A,object)
True #object是所有类的基类
2.isinstance(object A,classinfo B)
若第一个参数是第二个参数的实例对象,则返回true,否则false
1)若A是B的子类的实例,也返回True
2)若第一个参数不是对象,永远返回false
3)classinfo可以是类对象组成的元组,只要A是其中任何一个类的实例,即返回true
4)若B不是类或类对象组成的元组,则抛出TypeError
>>>issubclass(B,C)
False
>>>b1 = B()
>>>isinstance(b1,B)
True
>>>isinstance(b1,(A,B,C))
True
3.hasattr(object,name)
用于测试对象里是否有指定的属性
>>>class C:
def _ _init_ _(self,x=0):
self.x = x
>>>c1 = C()
>>>hassttr(c1,'x') #属性名加引号
True
4.getattr(object,name[,default])
返回对象指定的属性值,若不存在,则返回default的值,若未设置,则抛出AttributeError异常
>>>getattr(c1,'x')
0
>>>getattr(c1,'y','that is null')
'that is null'
5.setattr(object,name,value)
用于设置对象中指定属性的值,若不存在,则新建属性并赋值
>>>setattr(c1,'y','haha')
>>>getattr(c1,'y')
'haha'
6.delattr(object,name)
用于删除对象中指定属性,若不存在,则抛出AttributeError异常
>>>delattr(c1,'y')
7.property(fget=None,fset=None,fdel=None,doc=None)
通过属性设置属性的方法
class C:
def _ _init_ _(self,size=10):
self.size = size
def getSize(self):
return self.size
def setSize(self,value):
self.size = value
def delSize(self):
del self.size
x = property(getSize,setSize,delSize)
>>>c.x
10
>>>c.x = 12
>>>c.x
12
>>>c.size
12
>>>del c.x
>>>c.size
#AttributeError
property()返回可以设置属性的属性,参数分别是属性的操作方法
有了property()后当用户访问size属性时,只提供了x属性,当操作方法改变时,只需相应调整property()的参数,用户仍只需要操作x属性