title: ‘python——day_10:魔法方法’
date: 2019-11-05 20:08:56
categories:
魔法方法总是被双下划线包围
魔法方法是面向对象的python的一切
# 为什么类中有时候有__init__?因为需求
class Rectangle:
def __init__(self,x,y):
self.x = x
# 这里是可以理解为 self.x是实例化对象的元素
self.y = y
def getPeri(self):
return (self.x+self.y)*2
def getArea(self):
return self.x*self.y
rect = Rectangle(3,4)
rect.getPeri()
__init__函数没有返回值:
class A:
def __init__(self):
return "1"
a = A()#不要给init做返回
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-8592369aa820> in <module>
2 def __init__(self):
3 return "1"
----> 4 a = A()
TypeError: __init__() should return None, not 'str'
new(cls[…])第一个被调用的方法,返回cls的对象
# __new__(cls[....])第一个被调用的方法,返回cls的对象
class CapStr(str):
def __new__(cls,string):
string = string.upper()#变成大写后字符串
return str.__new__(cls,string)
a = CapStr("I love FishC.com")
a#解释是因为重写了str的方法,所以这里返回的就是默认转换为大写
'I LOVE FISHC.COM'
del(self)当对象销毁的时候,自动调用,垃圾回收机制自动销毁
#__del__(self)当对象销毁的时候,自动调用,垃圾回收机制自动销毁
class C:
def __init__(self):
print("我是__init__方法,我被调用了")
def __del__(self):
print("我是del方法")
c1 = C()
我是__init__方法,我被调用了
类似于type也是一个__init__方法
type(len)
builtin_function_or_method
type(int)
type
class C:
pass
type(C)#工厂函数就是类对象
__add__方法:
#这里贴图片
class New_int(int):
def __add__(self,other):
return int.__sub__(self,other)
a = New_int(1)
b = New_int(3)
a+b
-2
错误实例:无限递归
#自己重写
class Try_int(int):
def __add__(self,other):
return self+other
a = Try_int(1)
b = Try_int(3)
a+b# 先调用a的add方法,self就是a,others是b,然后+又来,然后递归了
#无限递归了
反运算操作符
# 反运算操作符
class Nint(int):
def __radd__(self,other):
return int.__sub__(self,other)
1+b
# 反运算操作符
class Nint(int):
def __rsub__(self,other):
return int.__sub__(self,other)
a = Nint(5)
3 - a
import time as t
class MyTimer():
def __init__(self):
self.prompt = "未开始计时"
self.unit= ['年','月','日','时','分','秒']
self.lasted = []
# self.start = 0# 属性覆盖方法
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.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
t1 = MyTimer()
举个简单例子:
class C:
def __init__(self):
self.x = 'x-man'
c = C()
c.x
对属性访问抽象方法的解释:
class C:
def __getattribute__(self,name):#定义当该类的属性被访问时候的行为
print("getattribute")
return super().__getattribute__(name)
def __getattr__(self,name):#定义当用户试图获取一个不存在的属性时的行为
print("getattr")
def __setattr__(self,name,value):# 当一个属性被设置的行为
print("setattr")
super().__setattr__(name,value)
def __delattr__(self,name):# 定义当一个属性被删除时候的行为
print("delattr")
super().__delattr__(name)
c = C()
c.x
#
错误实例:
#实例
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
def getarea(self):
return self.width *self.height
r1 = Rectangle(4,5)
#报错原因时 init函数,然后递归调用自身
修改上面代码:
#修改
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:
super().__setattr__(name,value)
def getarea(self):
return self.width *self.height
r1 = Rectangle(4,5)
描述符就是将某种特殊属性的类的实例指派给另一个类的属性
get(self,instance,owner)
用于访问属性,它返回属性的
set(self,instance,value)
将在属性分配操作中调用,不返回任何内容
delete(self,instance)
控制删除操作,不返回任何内容
实例1:
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("delete...",self,instance)
class Test:
x = MyDecriptor()
test = Test()
test.x
getting.. <__main__.MyDecriptor object at 0x0000014CBBF3BD30> <__main__.Test object at 0x0000014CBB9A8898> <class '__main__.Test'>
实例2:
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 __delete__(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 = 1
c.x
1
实例三:
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 = Celsius()
fah = Fahrenheit()
temp = Temperature()
temp.cel
temp.cel = 30
temp.fah
实例:
class CountList:
def __init__(self,*args):
self.values = [x for x in args]
self.count = {}.fromkeys(range(len(self.values)),0)
def __len__(self):
return len(self.values)
def __getitem__(self,key):
self.count[key]+=1
return self.values[key]
for i in "fishc":
print(i)
links = {"小甲鱼":"采购","鱼":'金鱼'}
for each in links:
print("%s->%s"%(each,links[each]))
it = iter(string)
while True:
try:
each = next(it)
except StopIteration:
break
print(each)
迭代器魔法方法
# 迭代器魔法方法 __iter__() __next__()
class Fibs:
def __init__(self):
self.a = 0
self.b = 1
def __iter__(self):
return self
def __next__(self):
self.a,self.b = self.b,self.a+self.b
return self.a
fibs = Fibs()
for each in fibs:
if each < 20:
print(each)
# 生成器:
a = [i for i in range(100) if not(i%2) and i % 3]
c = {i for i in [1,1,2,3,5]}