1.构造和析构
-魔法方法总是 被双下划线包围
-魔法方法是面向对象的Python的一切,如果你不知道魔法方法,说明你还没能意识到面向对象的Python的强大
-他们总能在适当的时候被 自动调用
__init__(self[,...]) 类在实例化对象的时候,就会自动调用的方法 返回值是none, 但是却不是实例化时调用的第一个方法
__new__(cls[,...])实例化时,调用的第一个方法
我们大多数时候不会重写它
因为str是不可改变的类型
>>> class CapStr(str):
def __new__(cls,string):
string = string.upper()
return str.__new__(cls,string)
>>> a=CapStr("i love yOU")
>>> a
'I LOVE YOU'
__del__(self) 析构器 垃圾回收机制自动调用这个方法
2.python会更灵活
>>> class int(int):
def __add__(self,o):
return int.__sub__(self,o)
>>> a = 5
>>> b= 3
>>> a+b
8
>>> a = int("5")
>>> b = int(3)
>>> a + b
2
3.反运算
a + b 当a对+ 不支持时,就会调用b的+的反运算
>>> class Nint(int):
def __radd__(self,o):
return int.__sub__(self,o)
>>> a = Nint(5)
>>> b = Nint(3)
>>> a+b
8
>>> 1+b #3-1=2
2
4.简单定制(计时器)
5.属性访问
>>> class C:
def __init__(self):
self.x = 'x-Man'
>>> c = C()
>>> c.x
'x-Man'
>>> getattr(c,'x','没有')
'x-Man'
>>> getattr(c,'y','no attribute')
'no attribute'
属性访问 的魔法方法
class Rectangle:
def __init__(self,width = 0,height = 0):
self.width = width
self.height = height
def __setattr__(self, key, value):
if key == 'square':
self.width = value
self.height = value
else:
self.key = value
def getArea(self):
return self.width * self.height
以上会出现死循环。
修改一下(调用基类的__setattr__):
或者
6.描述符:将某种特殊类型(要实现__get__,__set__,__del__三个中至少一个)的类的实例指派给另一个类的属性。
>>> class MyDecripptor:
def __get__(self,instance,owner):
print("getting",self,instance,owner)
>>> class Test:
x = MyDecripptor()
>>> 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):
return self.fset(instance,value)
def __del__(self,instance):
self.fdel(instance)
>>> class C:
def __init__(self):
SyntaxError: invalid syntax
>>> 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'
>>> c._x
7.定制容器
如果定制的容器是不可改变的话,你只需要定义__len__()和__getitem__()方法
如果定制的容器是可变的话,除了__len__()和__getitem__()方法,还需要定义___setitem__()和__delitem__()两个方法
不可改变的列表,统计访问次数
-魔法方法总是 被双下划线包围
-魔法方法是面向对象的Python的一切,如果你不知道魔法方法,说明你还没能意识到面向对象的Python的强大
-他们总能在适当的时候被 自动调用
__init__(self[,...]) 类在实例化对象的时候,就会自动调用的方法 返回值是none, 但是却不是实例化时调用的第一个方法
__new__(cls[,...])实例化时,调用的第一个方法
我们大多数时候不会重写它
因为str是不可改变的类型
>>> class CapStr(str):
def __new__(cls,string):
string = string.upper()
return str.__new__(cls,string)
>>> a=CapStr("i love yOU")
>>> a
'I LOVE YOU'
__del__(self) 析构器 垃圾回收机制自动调用这个方法
2.python会更灵活
>>> class int(int):
def __add__(self,o):
return int.__sub__(self,o)
>>> a = 5
>>> b= 3
>>> a+b
8
>>> a = int("5")
>>> b = int(3)
>>> a + b
2
3.反运算
a + b 当a对+ 不支持时,就会调用b的+的反运算
>>> class Nint(int):
def __radd__(self,o):
return int.__sub__(self,o)
>>> a = Nint(5)
>>> b = Nint(3)
>>> a+b
8
>>> 1+b #3-1=2
2
4.简单定制(计时器)
import time as t
class MyTimeer():
def __init__(self):
self.prompt = "no start..."
self.lasted = []
self.startNum = 0
self.stopNum = 0
def __str__(self):
return self.prompt
__repr__ = __str__
def start(self):
self.startNum=t.localtime()
print("start...")
def stop(self):
self.stopNum= t.localtime()
self.__calc()
print("stop...")
def __calc(self):
self.lasted = []
self.prompt = "all time is"
for index in range(6):
self.lasted.append(self.stopNum[index]-self.startNum[index])
self.prompt += str(self.lasted[index])
t1 = MyTimeer()
t1.start()
for i in range(99999):
print(" ")
t1.stop()
print(t1)
5.属性访问
>>> class C:
def __init__(self):
self.x = 'x-Man'
>>> c = C()
>>> c.x
'x-Man'
>>> getattr(c,'x','没有')
'x-Man'
>>> getattr(c,'y','no attribute')
'no attribute'
属性访问 的魔法方法
class Rectangle:
def __init__(self,width = 0,height = 0):
self.width = width
self.height = height
def __setattr__(self, key, value):
if key == 'square':
self.width = value
self.height = value
else:
self.key = value
def getArea(self):
return self.width * self.height
以上会出现死循环。
修改一下(调用基类的__setattr__):
class Rectangle:
def __init__(self,width = 0,height = 0):
self.width = width
self.height = height
def __setattr__(self, key, value):
if key == 'square':
self.width = value
self.height = value
else:
super.__setattr__(key,value)
def getArea(self):
return self.width * self.height
或者
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.__dict__[name] = value
def getArea(self):
return self.width * self.height
r1 = Rectangle(4,5)
print(r1.getArea())
r1.square = 10
print(r1.width)
print(r1.getArea())
6.描述符:将某种特殊类型(要实现__get__,__set__,__del__三个中至少一个)的类的实例指派给另一个类的属性。
>>> class MyDecripptor:
def __get__(self,instance,owner):
print("getting",self,instance,owner)
>>> class Test:
x = MyDecripptor()
>>> 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):
return self.fset(instance,value)
def __del__(self,instance):
self.fdel(instance)
>>> class C:
def __init__(self):
SyntaxError: invalid syntax
>>> 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'
>>> c._x
7.定制容器
如果定制的容器是不可改变的话,你只需要定义__len__()和__getitem__()方法
如果定制的容器是可变的话,除了__len__()和__getitem__()方法,还需要定义___setitem__()和__delitem__()两个方法
不可改变的列表,统计访问次数
class CountList:
def __init__(self,*arg):
self.values = [x for x in arg]
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]
c1 = CountList(1,3,5,7,9)
c2 = CountList(2,4,6,8,10)
print(c1[1])
print(c2[1])
print(c1[1]+c2[1])
print(c1.count)
8.迭代
对字典进行迭代:
利用iter()和next()进行迭代
9.生成器(也是一个迭代器的实现)
所谓协同程序就是可以运行独立函数调用,函数可以暂停或者挂起,并在需要的时候从程序离开的地方继续或者重新开始。
各种推导式: