python的魔法方法

来源:互联网 发布:淘宝名店 编辑:程序博客网 时间:2024/05/02 05:35
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.简单定制(计时器)
import time as tclass 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.heightr1 = Rectangle(4,5)print(r1.getArea())r1.square = 10print(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.生成器(也是一个迭代器的实现)

所谓协同程序就是可以运行独立函数调用,函数可以暂停或者挂起,并在需要的时候从程序离开的地方继续或者重新开始。




各种推导式:


原创粉丝点击