python学习日记12

今天开始学习魔法方法和特性。

魔法方法

魔法(特殊)方法是开头结尾都是两个下划线的名称。

构造函数

构造函数会在创建后自动调用,以init命名:

class foo:
    def __init__(self,val=6):
        self.exp=val
bar=foo()
print(bar.exp)
bar1=foo(7)
print(bar1.exp)

在继承中,构造函数会被覆盖,我们可以这样解决覆盖问题:

class foo:
    def __init__(self,val=6):
        self.exp=val
class foo2(foo):
    def __init__(self):
        foo.__init__(self)
        self.vall=1

我们也可以使用函数super:

class foo:
    def __init__(self,val=6):
        self.exp=val
class foo2(foo):
    def __init__(self):
        super().__init__()
        self.vall=1

基本的映射和序列协议

函数 作用
__len__(self) 返回集合包含的项数
__getitem__ (self,key) 返回与指定键关联的值
__setitem__ (self,key,value) 储存键-值对
__delitem__ (self,key) 删除键-值对

要了解更复杂的抽象基类,请阅读模块collections的文档。
我们可以实现一个无穷序列:

def check(key): #判断key是否可接受
    if not isinstance(key,int): raise TypeError
    if(key<0):raise IndexError
class seq:
    def __init__(self,start=0,step=1):#初始化起点和步长
        self.start=start
        self.step=step
        self.changed={}
    def __getitem__(self,key):#如果被修改就返回修改后的,没有则计算值
        check(key)
        try:return self.changed[key]
        except KeyError:
            return self.start+key*self.step
    def __setitem__(self,key,value):#赋新值
        check(key)
        self.changed[key]=value
s=seq(1,2)
print(s[2])
s[2]=100
print(s[2])

此类没有__len__,因为长度是无穷的。也不能使用del删除,因为没写delitem。

从list、dict和str继承

模块collections提供了抽象和具体的基类,我们也可以继承内置类型。

特性

我们可以用property来动态调整:

class seq:
    def __init__(self):
        self.start=0
        self.step=0
    def set(self,size):
        self.start,self.step=size
    def get(self):
        return self.start,self.step
    size=property(get,set)
s=seq()
s.start=1
s.step=2
print(s.size)
s.size=150,200
print(s.size)

关于装饰器,由于不常用,此处不作讨论。
我们可以拦截访问企图并自动调用类中的魔法方法:

函数 作用
__getattribute__(self,name) 访问时自动调用
__getattr__ (self,name) 属性被访问而对象没有这样的属性时自动调用
__setattr__ (self,name,value) 试图给属性赋值时自动调用
__delattr__ (self,name) 试图删除属性时自动调用

上面的无穷序列可以使用此法上面的示例而不用property。

知识共享许可协议
Text is available under CC BY-NC-SA 4.0 unless otherwise stated.

除非特殊声明,本站所有内容均以 CC BY-NC-SA 4.0协议授权。
上一篇
下一篇