39 类、类对象、对象实例
对象实例的变量名称和方法名称时,方法会被覆盖
>>>class BB:
def printBB():
print("no zuo no die")
>>>BB.printBB()
>>>bb =BB()
>>>bb.printBB() 无法调用 bb.prntBB(self)
class CC:
def setXY(self,x,y):
self.x=x
self.y=y
def printXY(self):
print(self.x,self.y)
>>>dd = CC()
>>>dd.__dict__
{} #为空初始化的对象实例 属性和方法为空
>>>cc.__dict__ #用户定义类的属性和方法
>>>dd.setXY(4,5) #默认传入的self为dd
>>>dd.__dict__
{'y':5,'x':4}
#类 被删除时 静态编码和方法 都还在内存中,类的实例化对戏
还可以调用方法
=====类和对象:相关的BIF 内置函数=========================
1、issubclass(class,classinfo)
判断是否是子类
class A:
pass
class B(A):
pass
issubclass(B,A) 为 True
2、isinstance(object,classinfo)
实例对象 和类的父类 也是实例的关系
判断实例对象 是不是类的实例
3、hasattr(object,name)
是否有属性
#注意 name 一定要加上单引号
4、getattr(object,name[,default])
取得对象的参数x的值
getattr(c,'x','-1') 不存在参数x返回 -1 如果不在上 default 会抛出异常
5、setattr(object,name,value)
设置属性的值,属性不存在新增
6、delattr(object,name)
删除object对象的name属性
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
x= property(getSize,setSize,delSize)
使用方法
c1=C()
查询:c1.x 与 c1.getSize() 效果一样
赋值:c1.x=18 与 c1.setSize(18) 效果一样
删除参数: del c1.x
有点类似 接口的封装
用户只要知道 x的参数操作就可以了
==============================
41 魔法方法:构造和析构
魔法方法使用双下划线 例如 __init__()
__init__(self[,...])
class Rectangle:
def __init__(self,x,y):
self.x=x
self.y=y
def getPeri(self):
retrun(self.x+self.y)*2
__init__(self[,..]) 不能跟返回值
使用案例
rect= Rectangle(3,4)
====================================
__new__(cls[,...]) Python 第一个被调用的方法
当继承一个不可变的类的时候,有需要调整类
的类型,可以重写 __new__()
当类继承 str(不可变类),必须重写 __new__,否则新类自动掉基类的__new__()方法
>>>class CapStr(str):
def __new__(cls,string):
string =string.upper()
return str.__new__(cls,string)
>>>c= Capstr("i love qian")
I LOVE QIAN
-----------------------------------------
__del__()
>>>class C:
del __init__(self):
print("我是__init__方法,我被调用了。。“)
del __del__(self):
print("我是del")
当所有 对对象实例的引用,垃圾回收机制 才会执行 __del__();
#42 算数运算
>>> a = int('123')
>>>b = int('456')
>>>a+b
579
>>>class New_int(int):
def __add__(self,other)
return int.__sub__(self,other)
方法集
__add__(self,other) :+
__sub__(self,other): -
__mul__(self,other):*
__truediv__(self,other): / 真除法
__floordiv__(self,other): // 整数除法
__mod__(self,other): % 取模算法
__divmod__(self,other): 定义 divmod() 结果是余数
__pow__(self,other[,modulo]): 定义 power(),**(幂运算符)
__lshift__(self,other) :<<
__rshift__(self,other):>>
__and__(self,other):&(按位 与操作)
__or__(self,other):|(按为或操作)
__xor__(self,other):^(按位异或操作)
# 43 算数运算2
__radd__(self,other): 反运算
例如 a+b
如果 a 没有 add方法,则使用 b的 radd方法
一元操作符
__neg__(self) : +X
__pos__(self) : -X
_abs__(self): abs() 取绝对值
__invert__(self) :按位求反 ~X
类型转换
======================================
# 44 简单定制
import time as t
class MyTime:
def __init__(self):
self.unit =['年','月','天','小时','分钟','秒']
self.prompt = "未开始计时!"
self.lasted =[]
self.begin = 0
self.end = 0
def __str__(self):
return self.prompt
__repr__=__str__
def __add__(self,other):
prompt = "总共运行了"
result =[]
for index in range(6):
result.append(self.lasted[index]+other.lasted[index])
if result[index] :
prompt+=str(result[index])+self.unit[index]
return prompt
# 开始计时
def start(self):
self.begin = t.localtime()
self.prompt ="提示,请先调用 stop()停止计时!"
print("计时开始...")
# 停止计时
def stop(self):
if not self.begin:
print("提示:请先调用start()进行计时!")
else:
self.end = t.localtime()
self._calc()
print("计时结束...")
# 内部方法,计算运用之间
def _calc(self):
self.lasted = []
self.prompt= "总共运行了"
for index in range(6):
self.lasted.append(self.end[index]-self.begin[index])
if self.lasted[index] :
self.prompt+=str(self.lasted[index])+self.unit[index]
print(self.prompt)
#为下一轮重新计时
self.begin = 0
self.end = 0
# 45 魔法方法:属性访问
=====类和对象:相关的BIF 内置函数=========================
1、getattr(object,name[,default])
取得对象的参数x的值
getattr(c,'x','-1') 不存在参数x返回 -1 如果不在上 default 会抛出异常
2、setattr(object,name,value)
设置属性的值,属性不存在新增
3、delattr(object,name)
删除object对象的name属性
4、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
x= property(getSize,setSize,delSize)
使用方法
c1=C()
查询:c1.x 与 c1.getSize() 效果一样
赋值:c1.x=18 与 c1.setSize(18) 效果一样
删除参数: del c1.x
有点类似 接口的封装
用户只要知道 x的参数操作就可以了
========================
__gettattr__(self,name)
-定义当用户试图获取一个不存在的属性时的行为
__getattribute__(self,name)
-定义当该类的属性被访问是的行为
__setattr__(self,name,value)
-定义当一个属性被设置是的行为
__delattr__(self,name)
-定义当一个属性被删除是的行为
class C:
def __getattribute__(self,name):
print("aaaa")
return super().__getattribute__(name)
def __getattr__(self,name):
print("__getattr_")
def __setattr__(self,name,value):
print("__setattr__")
return super().__setattr__(name,value)
def __delattr__(self,name):
print("__delattr__")
return super().__delattr__(name)
例子:
class Rectangle:
def __init__(self,width=0,height=0):
self.width = width
self.height = height
def __setattr__(self,name,value):
if name == 'square':
self.width = value
self.height = value
else:
#错误 self.name=value 会造成 死循环
#super().__setattr__(name,value)
self.__dict__[name]=value
def getArea(self):
return self.width * self.height
# 46 魔法方法:描述符(Property 的原理)
描述符就是 将某种特殊类型的类的实例指派另一个的类
的一个属性
__get__(self,instance,owner)
-用户访问属性,它返回属性的值
__set__(self,instance,value)
-将在属性分配操作中调用,不返回任何值
__delete__(self,instance)
-控制删除操作,不返回任何内容
>>> class MyDecriptor:
def __get__(self,instance,owner):
print("getting...",self,instance,owner)
def __set__(self,instance, value):
print("setting...",self,instance,value)
def __delete__(self,instance):
print("deleteing...",self,instance)
>>> class Test:
x = MyDecriptor()
>>> test = Test()
>>> test.x
getting... <__main__.MyDecriptor object at 0x0000026B0B00B9E8> <__main__.Test object at 0x0000026B0B06B4E0> <class '__main__.Test'>
>>> class MyProperty:
def __init__(self,fget=None,fset=None,fdel=None):
self.fget=fget
self.fset=fset
self.fdel=fdel
def __get__(self,instance,owner):
return self.fget(instance)
def __set__(self,instance,value):
self.fset(instance,value)
def __del__(self,instance):
self.fdel(instance)
>>> class C:
def __init__(self):
self._x = None
def getX(self):
return self._x
def setX(self,value):
self._x=value
def delX(self):
del self._x
x = MyProperty(getX,setX,delX)
>>> c =C()
>>> c.x='X-man'
>>> c._x
'X-man'
__x 私有变量 无法赋值
例子:
class Celsius:
def __init__(self,value = 26.0):
self.value = float(value) #唯一存放值的地方
def __get__(self,instance,owner):
return self.value
def __set__(self,instance,value):
self.value = float(value)
class Fahrenheit:
def __get__(self,instance,owner):
return instance.cel* 1.8 +32
def __set__(self,instance,value):
instance.cel = (float(value)-32)/1.8
class Temperature:
#cel 和 fah 都是描述符
cel = Celsius() #都没有存放值 c
fah = Fahrenheit() #都没有存放值
========== RESTART: D:\soft\python_3.5.1.amd64_AnXia\coding\temp.py ==========
>>> temp = Temperature()
>>> temp.cel
26.0
>>> temp.fah
78.80000000000001
>>> temp.cel=36
>>> temp.cel
36.0
>>> temp.fah
96.8
# 47 魔法方法:定制序列