python 双下划线函数

发布时间 2023-03-27 13:38:31作者: niko5960

双下划线函数在相应函数调用实例的时候会自动调用

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

8,``