博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2017年4月25日 python 之__setitem__,__getitem,__delitem__等属性
阅读量:5996 次
发布时间:2019-06-20

本文共 5984 字,大约阅读时间需要 19 分钟。

__setitem__,__getitem,__delitem__

#以字典格式操作对象的属性class Foo:    def __init__(self,name):        self.name=name    def __getitem__(self, item):        print(self.__dict__[item])    def __setitem__(self, key, value):        self.__dict__[key]=value    def __delitem__(self, key):        print('del obj[key]时,我执行')        self.__dict__.pop(key)    def __delattr__(self, item):        print('del obj.key时,我执行')        self.__dict__.pop(item)f=Foo("adamander")print(f.name)print(f['name'])f['age']=18f['age1']=19print(f['age'])print(f.age1)del f.age1del f['age']print(f.__dict__)

__slots__:

#使用类.xxx,或者对象.xxx,来访问属性本质就是在访问类或者对象的__dict__属性字典(类的字典是共享的,而每个实例的字典是独立的)#字典会占用大量的内存,如果有一个属性很少的类,但是实例很多的类,用__slots__来代替__dict__,限制对象属性数量,对所有对象属性统一管理,#节省内存.缺点是不能再给实例添加新属性,只能用里面有的。class People:    __slots__ = ['x','y','z']p=People()p.x=10p.y=20p.z=30print(p.x,p.y,p.z)

利用__iter__和__next__实现迭代器和range():

#实现迭代器协议from collections import Iterable,Iteratorclass Foo:    def __init__(self,start):        self.start=start    def __iter__(self):        return self    def __next__(self):        n=self.start        self.start+=1        return nf=Foo(0)print(next(f))print(next(f))print(next(f))print(next(f))print(next(f))print(next(f))print(next(f))print(next(f))print(next(f))print(next(f))#一直不停的往下加# for i in f:#     print(i)
# 实现range()class Range:    def __init__(self,start,end):        self.start=start        self.end=end    def __iter__(self):        return self    def __next__(self):        if self.start==self.end:            raise StopIteration        n=self.start        self.start+=1        return nfor i in Range(3, 8):    print(i)

 

__doc__:描述文档

class Foo:    '我是class描述信息'    passprint(Foo.__doc__)#输出:我是class描述信息
#该属性无法继承给子类
def Func():    '我是def描述信息'    passprint(Func.__doc__)#输出:我是def描述信息

__del__:析构方法

# 析构方法___del__析构方法,当对象在内存中被释放时,自动触发执行。# 注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,# 因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。#垃圾回收机制,del 立即删除,不然等其他执行完毕,自动回收import timeclass Open:    def __init__(self,filename,mode='r',encoding='utf-8'):        self.file=open(filename,mode,encoding=encoding)    def __enter__(self):        print("enter=====>")        return self    def write(self,line):        t=time.strftime('%Y-%m-%d %T')        self.file.write('%s %s' %(t,line))    def __getattr__(self, item):        return getattr(self.file,item)    def __del__(self):        print("===>del")            def __exit__(self, exc_type, exc_val, exc_tb):        # print("exit")        # print("exc_type",exc_type)        # print("exc_val",exc_val)        # print("exc_tb",exc_tb)        self.file.close()with Open('b.txt','w+') as f:    f.write("xxxx")    f.write("xxxx")    f.write("xxxx")

__call__:是否可调用

# __call__实例调用,没有他,实例是不可调用的class People:    def __init__(self,name):        self.name=name    # def __call__(self, *args, **kwargs):    #     passp=People("ada")print(callable(People))  #Trueprint(callable(p))#False,然而放开注释就是True

__enter__和__exit__:

# with open('a.txt') as f:#   '代码块'# 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法class Open:    def __init__(self,name):        self.name=name    def __enter__(self):        print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量,即f')        # return self    def __exit__(self, exc_type, exc_val, exc_tb):        print('当with中代码块执行完毕时执行我')with Open('a.txt') as f:    print('=====>执行代码块')    # print(f,f.name)        # 运行结果:# 出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量,即f# =====>执行代码块# 当with中代码块执行完毕时执行我

 

metaclass 元类:

# typer===>produce class===>produce obj# type称谓元类,是所有类的类,利用type控制类的行为, 模拟class关键字创建类的过程class Foo:    x=1    def run(self):        passprint(type(Foo))class_name="Bar"def Run(self):    print("%s is running"%self.name)bases=(object,)class_dic={    "x":1,    "run":Run}Bar=type(class_name,bases,class_dic)print(Bar)print(type(Bar))print(type("123"))print(type(123))# 运行结果:# 
#
#
#
#
元类是类的类,是类的模板元类是用来控制如何创建类的,正如类是创建对象的模板一样元类的实例为类,正如类的实例为对象(f1对象是Foo类的一个实例,Foo类是 type 类的一个实例)type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象

创建类的两种方式:

# 创建类的两种方式# 方式一:class Foo:    def func(self):        print('from func')         # 方式二:x = 1def func(self):    print('from func') Foo=type('Foo',(object,),{
'func':func,'x':1})
#利用元类来设计一个类,要求类内的函数必须写注释class Mymeta(type):    def __init__(self,class_name,class_bases,class_dic):        for key in class_dic:            if not callable(class_dic[key]):continue            if not class_dic[key].__doc__:                raise TypeError("all the func must be notes")class Foo(metaclass=Mymeta):    x=1    def run(self):        '所有函数必须写注释'        print("class Foo")Foo()

终极:盗墓笔记的终极

#元类总结class Mymeta(type):    def __init__(self,name,bases,dic):        print('===>Mymeta.__init__')    def __new__(cls, *args, **kwargs):        print('===>Mymeta.__new__')        return type.__new__(cls,*args,**kwargs)    def __call__(self, *args, **kwargs):        print('aaa')        obj=self.__new__(self)        self.__init__(self,*args,**kwargs)        return objclass Foo(object,metaclass=Mymeta):    def __init__(self,name):        self.name=name    def __new__(cls, *args, **kwargs):        return object.__new__(cls)'''需要记住一点:名字加括号的本质(即,任何name()的形式),都是先找到name的爹,然后执行:爹.__call__而爹.__call__一般做两件事:1.调用name.__new__方法并返回一个对象2.进而调用name.__init__方法对儿子name进行初始化''''''class 定义Foo,并指定元类为Mymeta,这就相当于要用Mymeta创建一个新的对象Foo,于是相当于执行Foo=Mymeta('foo',(...),{...})因此我们可以看到,只定义class就会有如下执行效果===>Mymeta.__new__===>Mymeta.__init__实际上class Foo(metaclass=Mymeta)是触发了Foo=Mymeta('Foo',(...),{...})操作,遇到了名字加括号的形式,即Mymeta(...),于是就去找Mymeta的爹type,然后执行type.__call__(...)方法于是触发Mymeta.__new__方法得到一个具体的对象,然后触发Mymeta.__init__方法对对象进行初始化''''''obj=Foo('egon')的原理同上''''''总结:元类的难点在于执行顺序很绕,其实我们只需要记住两点就可以了1.谁后面跟括号,就从谁的爹中找__call__方法执行type->Mymeta->Foo->objMymeta()触发type.__call__Foo()触发Mymeta.__call__obj()触发Foo.__call__2.__call__内按先后顺序依次调用儿子的__new__和__init__方法'''

 

转载于:https://www.cnblogs.com/adamans/articles/6762560.html

你可能感兴趣的文章
07.GitHub实战系列~7.Git之VS2013团队开发(如果不想了解git命令直接学这篇即可)...
查看>>
网站整体解决方案
查看>>
oracle11g R2 grid和database卸载
查看>>
Servlet 上传文件
查看>>
我对什么是真正的对象,以及软件中的对象在分析阶段、设计阶段、实现阶段的一些看法...
查看>>
如何监控你的鼠标
查看>>
Ubuntu安装MySQL
查看>>
Google Zxing 二维码生成与解析
查看>>
jdk 源码 精巧部分 收集 (一)
查看>>
JAVA抓取网页的图片
查看>>
追本溯源,看云效平台如何帮企业提升研发效能
查看>>
MySQL数据库复制概念及数据库架构不断扩展方案
查看>>
EF-DbUpdateException解决方案
查看>>
Scalaz(19)- Monad: \/ - Monad 版本的 Either
查看>>
MS SQL 监控磁盘空间告警
查看>>
strong vs copy
查看>>
算法系列15天速成——第四天 五大经典查找【上】
查看>>
Gradle Construction Project -- HelloGradle
查看>>
基于Java、jQuery应用的账务管理系统开源了(09.3.19更新)
查看>>
第一章、操作系统基本简介
查看>>