python的魔法方法

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.生成器(也是一个迭代器的实现)

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




各种推导式:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值