双下划线函数在相应函数调用实例的时候会自动调用
1,__repr__
class CLanguage:
pass
clangs = CLanguage()
print(clangs)
当print调用时会自动调用repr函数,一般情况下输出的是一个对象的地址<__main__.CLanguage object at 0x000001A7275221D0>
,重写repr函数即可输出自定义类信息
class CLanguage:
def __init__(self):
self.name = "C语言中文网"
self.add = "http://c.biancheng.net"
def __repr__(self):
return "CLanguage[name="+ self.name +",add=" + self.add +"]"
clangs = CLanguage()
print(clangs)
2,__str()__
使用print的时候,print会调用__str()__方法,打印自定义信息
会先尝试str()函数,再尝试repr()函数,str()函数只有在print的时候才会调用,repr()在调用该对象的时候就会自动调用。
class Test(object):
def __init__(self, value='hello, world!'):
self.data = value
>>> t = Test()
>>> t
<__main__.Test at 0x7fa91c307190>
>>> print t
<__main__.Test object at 0x7fa91c307190>
# 看到了么?上面打印类对象并不是很友好,显示的是对象的内存地址
# 下面我们重构下该类的__repr__以及__str__,看看它们俩有啥区别
# 重构__repr__
class TestRepr(Test):
def __repr__(self):
return 'TestRepr(%s)' % self.data
>>> tr = TestRepr()
>>> tr
TestRepr(hello, world!)
>>> print tr
TestRepr(hello, world!)
# 重构__repr__方法后,不管直接输出对象还是通过print打印的信息都按我们__repr__方法中定义的格式进行显示了
# 重构__str__
class TestStr(Test):
def __str__(self):
return '[Value: %s]' % self.data
>>> ts = TestStr()
>>> ts
<__main__.TestStr at 0x7fa91c314e50>
>>> print ts
[Value: hello, world!]
# 你会发现,直接输出对象ts时并没有按我们__str__方法中定义的格式进行输出,而用print输出的信息却改变了
3,__len__
在使用len()函数的时候,会自动调用实例的__len__()方法
class Students():
def __init__(self, *args):
self.names = args
def __len__(self):
return len(self.names)
4,__getitem__
方法
__getitem__
实现了类的迭代,可以通过迭代器输出内容
import re
RE_WORD = re.compile(r'\w+')
class Sentence:
def __init__(self, text):
self.text = text
self.words = RE_WORD.findall(text) # re.findall函数返回一个字符串列表,里面的元素是正则表达式的全部非重叠匹配
def __getitem__(self, index):
return self.words[index]
输出
>>> s = Sentence('The time has come')
>>> for word in s:
print(word)
# 可以通过迭代器输出内容
The
time
has
come
>>> s[0]
'The'
凡是在类中定义了这个__getitem__ 方法,那么它的实例对象(假定为p),可以像这样p[key] 取值,当实例对象做p[key] 运算时,会调用类中的方法__getitem__。
一般如果想使用索引访问元素时,就可以在类中定义这个方法(getitem(self, key) ),当实例对象通过[] 运算符取值时,会调用它的方法__getitem__。
class DataBase:
'''Python 3 中的类'''
def __init__(self, id, address):
'''初始化方法'''
self.id = id
self.address = address
self.d = {self.id: 1,
self.address: "192.168.10.10",
}
def __getitem__(self, key):
# return self.__dict__.get(key, "100")
return self.d.get(key, "default")
data = DataBase(1, "192.168.2.11")
print(data["hi"])
print(data[data.id])
输出
default
1
5,__setitem__
在设置类实例属性时自动调用
class A:
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__:Set B Value BB
__setitem__:Set D Value DD
6,__delitem__()
这个方法在对对象的组成部分使用__del__语句的时候被调用,应删除与key相关联的值。同样,仅当对象可变的时候,才需要实现这个方法。
class Tag:
def __init__(self):
self.change={'python':'This is python',
'php':'PHP is a good language'}
def __getitem__(self, item):
print('调用getitem')
return self.change[item]
def __setitem__(self, key, value):
print('调用setitem')
self.change[key]=value
def __delitem__(self, key):
print('调用delitem')
del self.change[key]
a=Tag()
print(a['php'])
del a['php']
print(a.change)
输出
调用getitem
PHP is a good language
调用delitem
{'python': 'This is python'}
7,__contains__()
判断某元素在不在实例中
class Graph():
def __init__(self):
self.items = {'a':1,'b':2,'c':3}
def __str__(self):
return '打印我干嘛'
def __contains__(self,x): # x参数接受的就是我们手动传递的数据
if x<10 and x>0:
return True
return False
print(9 in Graph())
print(5 in Graph())
print(51 in Graph())
>> True
>> True
>> False