您的位置:首页 > 编程语言 > Python开发

python的魔法方法

2017-07-11 21:43 435 查看
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 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.生成器(也是一个迭代器的实现)

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





各种推导式:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: