一些常用的魔法函数

1. __ len__函数

在Python中,如果你调用len()函数试图获取一个对象的长度,实际上,在len()函数内部,它自动去调用该对象的__len__()方法。

classStudents():def__init__(self,*args):self.names=argsdef__len__(self):returnlen(self.names)ss=Students('Bob','Alice','Tim')print(len(ss))

输出结果:3

2. __getitem__函数

Python的特殊方法__getitem_() 主要作用是可以让对象实现迭代功能。我们通过一个实例来说明。

定义一个Sentence类,通过索引提取单词。

importreRE_WORD=re.compile(r'\w+')classSentence:def__init__(self,text):self.text=textself.words=RE_WORD.findall(text)# re.findall函数返回一个字符串列表,里面的元素是正则表达式的全部非重叠匹配def__getitem__(self,index):returnself.words[index]

测试:

>>>s=Sentence('The time has come')>>>forwordins:print(word)Thetimehascome>>>s[0]'The'>>>s[1]'time'

通过测试发现,示例 s 可以正常迭代。但是没有定义getitem() 测试则会报错,TypeError: '***' object is not iterable。

序列可以迭代:

我们都知道序列是可以迭代,下面具体说明原因。

解释器需要迭代对象x时, 会自动调用iter(x)方法。内置的 iter(x) 方法有以下作用:

检查对象是否实现了__iter__ 方法,如果实现了就调用它(也就是我们偶尔用到的特殊方法重载),获取一个迭代器。

如果没有实现iter()方法, 但是实现了 __getitem__方法,Python会创建一个迭代器,尝试按顺序(从索引0开始,可以看到我们刚才是通过s[0]取值)获取元素。

如果尝试失败,Python抛出TypeError异常,通常会提示TypeError: '***' object is not iterable。

任何Python序列都可迭代的原因是,他们都实现了__getitem__方法。其实,标准的序列也都实现了__iter__方法。

注意:从python3.4 开始,检查对象x能否迭代,最准确的方法是: 调用iter(x)方法,如果不可迭代,在处理TypeError异常。这比使用isinstance(x,abc.Iterable)更准确,因为iter()方法会考虑到遗留的__getitem__()方法,而abc.Iterable类则不考虑。

凡是在类中定义了这个__getitem__ 方法,那么它的实例对象(假定为p),可以像这样p[key] 取值,当实例对象做p[key] 运算时,会调用类中的方法__getitem__。

一般如果想使用索引访问元素时,就可以在类中定义这个方法(__getitem__(self, key) ),当实例对象通过[] 运算符取值时,会调用它的方法__getitem__。

classDataBase:'''Python 3 中的类'''def__init__(self,id,address):'''初始化方法'''self.id=idself.address=addressself.d={self.id:1,self.address:"192.168.10.10",}def__getitem__(self,key):# return self.__dict__.get(key, "100")returnself.d.get(key,"default")data=DataBase(1,"192.168.2.11")print(data["hi"])print(data[data.id])

输出结果:

default1

或者

classDataBase:'''Python 3 中的类'''def__init__(self,id,address):'''初始化方法'''self.id=idself.address=addressdef__getitem__(self,key):returnself.__dict__.get(key,"100")data=DataBase(1,"192.168.2.11")print(data["hi"])print(data["id"])

输出结果是:

1001

还可以用在对象的迭代上

classSTgetitem:def__init__(self,text):self.text=textdef__getitem__(self,index):result=self.text[index].upper()returnresultp=STgetitem("Python")print(p[0])print("------------------------")forcharinp:print(char)

输出结果是:

P------------------------PYTHON

3. __ setitem__函数

__setitem__(self,key,value):该方法应该按一定的方式存储和key相关的value。在设置类实例属性时自动调用的。

# -*- coding:utf-8 -*-classA:def__init__(self):self['B']='BB'self['D']='DD'def__setitem__(self,name,value):print"__setitem__:Set %s Value %s"%(name,value)if__name__=='__main__':X=A()

输出结果为:

__setitem__:SetBValueBB__setitem__:SetDValueDD

4. __ delitem__()

__delitem__(self,key):

这个方法在对对象的组成部分使用__del__语句的时候被调用,应删除与key相关联的值。同样,仅当对象可变的时候,才需要实现这个方法。

classTag:def__init__(self):self.change={'python':'This is python','php':'PHP is a good language'}def__getitem__(self,item):print('调用getitem')returnself.change[item]def__setitem__(self,key,value):print('调用setitem')self.change[key]=valuedef__delitem__(self,key):print('调用delitem')delself.change[key]a=Tag()print(a['php'])dela['php']print(a.change)

输出结果:

调用getitemPHPisagoodlanguage调用delitem{'python':'This is python'}

5. __contains__函数

在Class里添加__contains__(self,x)函数,可判断我们输入的数据是否在Class里.参数x就是我们传入的数据.

如下代码:

classGraph():def__init__(self):self.items={'a':1,'b':2,'c':3}def__contains__(self,x):# 判断一个定点是否包含在里面returnxinself.itemsa=Graph()print('a'ina)# 返回Trueprint('d'ina)# 返回False>>True>>False

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容