Python中的魔法属性

白癜风边上长黑点 http://m.39.net/baidianfeng/a_4379972.html
魔法属性

在Python中,所有以__双下划线包起来的方法,都统称为MagicMethod,例如类的初始化方法__init__(),实例对象创造方法__new__()等。

魔法属性和方法是Python内置的一些属性和方法,有着特殊的含义。命名时前后加上两个下划线,在执行系统特定操作时,会自动调用。

常见的魔法属性__doc__

表示类的描述信息

#__doc__classFoo:"""描述类信息,这是用于测试的类"""deffunc(self):pass#ipython测验In[2]:Foo.__doc__Out[2]:描述类信息,这是用于测试的类__module__和__class____module__表示当前操作的对象在那个模块__class__表示当前操作的对象的类是什么

#__module__、__class__#oop.pyclassStudent(object):def__init__(self,name):self.name=name#main.pyfromoopimportStudents=Student()print(s.__module__)#输出oop即:输出模块print(s.__class__)#输出classoop.Student即:输出类__init__、__new__

__init__()初始化方法和__new__(),通过类创建对象时,自动触发执行。__new__是用来创建类并返回这个类的实例,而__init__只是将传入的参数来初始化该实例。

__new__()创建对象时调用,会返回当前对象的一个实例

__init__()创建完对象后调用,对当前对象的一些实例初始化,无返回值

#__init__、__new__classStudent(object):def__init__(self,name,age):print(__init__()called)self.name=nameself.age=agedef__new__(cls,*args,**kwargs):print(__new__()called)print(cls,args,kwargs)returnsuper().__new__(cls)#ipython测验In[26]:s1=Student(hui,age=21)__new__()calledclass__main__.Student(hui,){age:21}__init__()calledIn[27]:s2=Student(jack,age=20)__new__()calledclass__main__.Student(jack,){age:20}__init__()called__del__

当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,有内存管理、垃圾回收机制,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,__del__的调用是由解释器在进行垃圾回收时自动触发执行的。

#__del__classFoo:def__del__(self):print(__del__()called)#ipython测验In[29]:f=Foo()In[30]:delf__del__()called__call__

让类的实例的行为表现的像函数一样,你可以调用它们,将一个函数当做一个参数传到另外一个函数中等等。这是一个非常强大的特性,其让Python编程更加舒适甜美。对象后面加括号,触发执行。

注:__init__方法的执行是由创建对象触发的,即:对象=类名();而对于__call__方法的执行是由对象后加括号触发的,即:对象()或者类()()

__call__在那些类的实例经常改变状态的时候会非常有效。调用这个实例是一种改变这个对象状态的直接和优雅的做法。用一个实例来表达最好不过了:

#__call__classRect(object)"""调用实例对象来改变矩形的位置"""def__init__(self,x,y):#x,y代表矩形坐标self.x,self.y=x,ydef__call__(self,x,y):#改变实体的位置self.x,self.y=x,y#ipython测验In[33]:r=Rect(10,10)In[34]:r.x,r.yOut[34]:(10,10)In[35]:r(0,0)In[36]:r.x,r.yOut[36]:(0,0)In[37]:r(,)In[38]:r.x,r.yOut[38]:(,)__dict__

类或对象中的所有属性

类的实例属性属于对象;类中的类属性和方法等属于类,即:

#__dict__classStudent(object):def__init__(self,name,age):self.name=nameself._age=age

propertydefage(self):returnself._age#ipython测验In[47]:#获取类属性In[48]:Student.__dict__Out[48]:mappingproxy({__module__:__main__,__init__:function__main__.Student.__init__(self,name,age),age:propertyat0xe2ae8,__dict__:attribute__dict__ofStudentobjects,__weakref__:attribute__weakref__ofStudentobjects,__doc__:None})In[49]:#获取实例对象的属性In[50]:s=Student(hui,21)In[51]:s.__dict__Out[51]:{name:hui,_age:21}In[52]:s2=Student(jack,20)In[53]:s2.__dict__Out[53]:{name:jack,_age:20}__str__

如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值。

In[65]:#__str__...:classFoo(object):...:pass...:In[66]:f=Foo()In[67]:print(f)__main__.Fooobjectat0x00000EIn[68]:classFoo(object):...:...:def__str__(self):...:returnCustomFooobjectstr...:In[69]:f=Foo()In[70]:print(f)CustomFooobjectstr__getitem__、__setitem__、__delitem__

用于索引操作,如字典。以上分别表示获取、设置、删除数据。

用于切片操作,如列表。

字典示例

#__getitem__、__setitem__、__delitem__classMyDict(object):def__init__(self):self.my_dict=dict()def__getitem__(self,key):print(__getitem__(),key)returnself.my_dict.get(key,None)def__setitem__(self,key,value):print(__setitem__(),key,value)self.my_dict.update(key=value)def__delitem__(self,key):print(__delitem__(),key)delself.my_dict[key]#ipython测验In[33]:mdict=MyDict()In[34]:print(mdict[name])__getitem__()nameNoneIn[35]:#新增In[36]:mdict[name]=hui__setitem__()namehuiIn[37]:mdict[age]=21__setitem__()age21In[38]:mdict[name]__getitem__()nameOut[38]:huiIn[39]:mdict[age]__getitem__()ageOut[39]:21In[40]:#更新In[41]:mdict[name]=jack__setitem__()namejackIn[42]:mdict[name]__getitem__()nameOut[42]:jackIn[43]:#删除In[44]:delmdict[age]__delitem__()ageIn[45]:print(mdict[age])__getitem__()ageNone列表示例

#切片操作classMyList(object):def__init__(self):self.mlist=list()def__getitem__(self,index):print(__getitem__()called)print(index)ifisinstance(index,slice):returnself.mlist[index]def__setitem__(self,index,value):print(__getitem__()called)print(index,value)ifisinstance(index,slice):self.mlist[index]=valuedef__delitem__(self,index):print(__delitem__()called)ifisinstance(index,slice):delself.mlist[index]#ipython测验In[70]:mlist=MyList()In[71]:mlist[0]__getitem__()called0In[72]:mlist[0:-1]__getitem__()calledslice(0,-1,None)Out[72]:[]In[73]:mlist[:]=[1,2,3]__getitem__()calledslice(None,None,None)[1,2,3]In[74]:mlist[:]__getitem__()calledslice(None,None,None)Out[74]:[1,2,3]In[75]:mlist[0:2]__getitem__()calledslice(0,2,None)Out[75]:[1,2]In[76]:mlist[::-1]__getitem__()calledslice(None,None,-1)Out[76]:[3,2,1]In[77]:mlist[0]__getitem__()called0In[78]:mlist[0:1]__getitem__()calledslice(0,1,None)Out[78]:[1]In[79]:delmlist[0:1]__delitem__()calledIn[80]:mlist[:]__getitem__()calledslice(None,None,None)Out[80]:[2,3]

注意:当进行mlist[0]操作的时候传递并不是一个slice对象,不是一个int类型的数字,所以不能把索引为0的值取出来,改成mlist[0,1]或者在__getitem__()的方法中新增数字判断,大家可以尝试一下。

__enter__、__exit__

with声明是从Python2.5开始引进的关键词。你应该遇过这样子的代码:

withopen(foo.txt)asbar:#dosomethingwithbarpass

在with声明的代码段中,我们可以做一些对象的开始操作和退出操作,还能对异常进行处理。这需要实现两个魔术方法:__enter__和__exit__。

__enter__(self):

定义了当使用with语句的时候,会话管理器在块被初始创建时要产生的行为。请注意,__enter__的返回值与with语句的目标或者as后的名字绑定。

__exit__(self,exception_type,exception_value,traceback):

定义了当一个代码块被执行或者终止后,会话管理器应该做什么。它可以被用来处理异常、执行清理工作或做一些代码块执行完毕之后的日常工作。如果代码块执行成功,exception_type,exception_value,和traceback将会为None。否则,你可以选择处理这个异常或者是直接交给用户处理。如果你想处理这个异常的话,请确保__exit__在所有语句结束之后返回True。如果你想让异常被会话管理器处理的话,那么就让其产生该异常。

__copy__、__deepcopy__

有时候,尤其是当你在处理可变对象时,你可能想要复制一个对象,然后对其做出一些改变而不希望影响原来的对象。这就是Python的copy所发挥作用的地方。

__copy__(self):

定义了当对你的类的实例调用copy.copy()时所产生的行为。copy.copy()返回了你的对象的一个浅拷贝——这意味着,当实例本身是一个新实例时,它的所有数据都被引用了——例如,当一个对象本身被复制了,它的数据仍然是被引用的(因此,对于浅拷贝中数据的更改仍然可能导致数据在原始对象的中的改变)。

__deepcopy__(self,memodict={}):

定义了当对你的类的实例调用copy.deepcopy()时所产生的行为。copy.deepcopy()返回了你的对象的一个深拷贝——对象和其数据都被拷贝了。memodict是对之前被拷贝的对象的一个缓存——这优化了拷贝过程并且阻止了对递归数据结构拷贝时的无限递归。当你想要进行对一个单独的属性进行深拷贝时,调用copy.deepcopy(),并以memodict为第一个参数。

这些魔术方法的用例看起来很小,并且确实非常实用.它们反应了关于面向对象程序上一些重要的东西在Python上,并且总的来说Python总是一个简单的方法去找某些事情,即使是没有必要的。这些魔法方法可能看起来不是很有用,但是一旦你需要它们,你会感到庆幸它们的存在。

其他魔法方法

由于魔法属性、方法太多了在这就不一一描述和展示了,其他的就以表格形式呈现吧。

用于比较的魔术方法方法作用__cmp__(self,other)比较方法里面最基本的的魔法方法__eq__(self,other)定义相等符号的行为,==__ne__(self,other)定义不等符号的行为,!=__lt__(self,other)定义小于符号的行为,__gt__(self,other)定义大于符号的行为,__le__(self,other)定义小于等于符号的行为,=__ge__(self,other)定义大于等于符号的行为,=数值计算的魔术方法单目运算符和函数方法作用__pos__(self)实现一个取正数的操作__neg__(self)实现一个取负数的操作__abs__(self)实现一个内建的abs()函数的行为__invert__(self)实现一个取反操作符(~操作符)的行为__round__(self,n)实现一个内建的round()函数的行为__floor__(self)实现math.floor()的函数行为__ceil__(self)实现math.ceil()的函数行为__trunc__(self)实现math.trunc()的函数行为双目运算符或函数方法作用__add__(self,other)实现一个加法__sub__(self,other)实现一个减法__mul__(self,other)实现一个乘法__floordiv__(self,other)实现一个//操作符产生的整除操作__div__(self,other)实现一个/操作符代表的除法操作__truediv__(self,other)实现真实除法__mod__(self,other)实现一个%操作符代表的取模操作__divmod__(self,other)实现一个内建函数divmod()__pow__(self,other)实现一个指数操作(******操作符)的行为__lshift__(self,other)实现一个位左移操作**()**的功能__rshift__(self,other)实现一个位右移操作**()**的功能__and__(self,other)实现一个按位进行与操作**()**的行为__or__(self,other)实现一个按位进行或操作的行为__xor__(self,other)异或运算符相当于^增量运算方法作用__iadd__(self,other)加法赋值__isub__(self,other)减法赋值__imul__(self,other)乘法赋值__ifloordiv__(self,other)整除赋值,地板除,相当于//=运算符__idiv__(self,other)除法赋值,相当于/=运算符__itruediv__(self,other)真除赋值__imod_(self,other)模赋值,相当于%=运算符__ipow__(self,other)乘方赋值,相当于**=运算符__ilshift__(self,other)左移赋值,相当于=运算符__irshift__(self,other)左移赋值,相当于=运算符__iand__(self,other)与赋值,相当于=运算符__ior__(self,other)或赋值__ixor__(self,other)异或运算符,相当于^=运算符类型转换方法作用__int__(self)转换成整型__long__(self)转换成长整型__float__(self)转换成浮点型__



转载请注明地址:http://www.sanbaicaoasb.com/scgj/8377.html
  • 上一篇文章:
  • 下一篇文章:
  • 热点文章

    • 没有热点文章

    推荐文章

    • 没有推荐文章