类的常用魔术方法:无需人为调用,基本是在特定的时刻自动触发,方法名被前后两个下划线包裹

魔术方法,总结表:

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

 魔术方法 Python

 



__init__:构造函数。初始化的时候调用。

__new__:对象实例化方法,其实这才是类里面第一个被调用的方法,在构造函数之前调用,之后才是__init__,只是这个比较特殊,一般不使用。

__call__:对象当函数的时候触发。

1     class A():
2         def __init__(self,name = 0):
3             print("哈哈,我是构造函数")
4     
5         def __call__(self):
6             print("我是__call__函数")
7      
8     a = A()
9     a()    #对象当函数使用,如果没有__call__函数会报错

 



__str__:当对象被当做字符串使用过的时候调用。

1     class A():
2         def __init__(self,name = 0):
3             print("哈哈,我是构造函数")
4      
5         def __str__(self):
6             return "我只是一个例子"
7      
8     a = A()
9     print(a)  #把对象当字符串使用

__repr__:返回字符串,跟__str__函数差不多。

 

 


属性操作相关:

__getattr__:访问不存在属性的时候触发。拦截点号运算。当对未定义的属性名称和实例进行点号运算时,就会用属性名作为字符串调用这个方法。如果继承树可以找到该属性,则不调用此方法

__setattr__:对成员属性进行设置的时候触发,有三个参数--

                         1,self用来获取当前对象

                         2,被设置的属性名称,以字符串形式出现

                         3,需要对属性名称设置的值

                       作用:进行属性设置的时候进行验证或者修改。
        会拦截所有属性的的赋值语句。如果定义了这个方法,self.arrt = value 就会变成self,__setattr__("attr", value).这个需要注意。

        当在__setattr__方法内对属性进行赋值是,不可使用self.attr = value,因为他会再次调用self,__setattr__("attr", value),则会形成

        无穷递归循环,最后导致堆栈溢出异常。应该通过对属性字典做索引运算来赋值任何实例属性,也就是使用self.__dict__['name'] = value.

1     A():
2         def __init__(self):
3             pass
4         def __setattr__(self, name, value):
5             print("设置属性:{0}".format(name))
6             self.name = value        #这句语句会导致死循环
7      
8     a = A()
9     a.age = 18

所以为了避免死循环,规定统一调用父类魔法函数:

1     class A():
2         def __init__(self):
3             pass
4         def __setattr__(self, name, value):
5             print("设置属性:{0}".format(name))
6             super().__setattr__(name,value)    #super函数调用父类,避免死循环
7      
8     a = A()
9     a.age = 18

 

 

 



如果在类中定义了__getitem__()方法,那么他的实例对象(假设为P)就可以这样P[key]取值。当实例对象做P[key]运算时,就会调用类中的__getitem__()方法。

 1     # -*- coding:utf-8 -*-
 2     class DataTest:
 3         def __init__(self,id,address):
 4             self.id=id
 5             self.address=address
 6             self.d={self.id:1,
 7                     self.address:"192.168.1.1"
 8                     }
 9             
10         def __getitem__(self,key):
11             return "hello"
12         
13      
14     data=DataTest(1,"192.168.2.11")
15     print data[2] 

 

__xxxitem__: 当以[ ” “ ] 的方式访问属性时,就会调用此类型的方法

setitem:当属性被以索引方式赋值的时候会调用该方法

getitem:一般如果想使用索引访问元素时,就可以在类中定义这个方法

delitem:当使用索引删除属性时调用该方法

实例

 1 __Author__ = "Lance#"
 2 
 3 # -*- coding = utf-8 -*-
 4 
 5 class Point:
 6     def __init__(self):
 7         pass
 8 
 9     def __str__(self):
10         return 'Point is (%s,%s)' %(self.x, self.y)
11 
12     def __setitem__(self, key, value):
13         print('Called the __setitem__ function')
14         self.__dict__[key] = value
15 
16     def __getitem__(self, item):
17         print('Called the __getitem__ function')
18         try:
19             if item == 'x':
20                 return '%s' %self.x
21             elif item == 'y':
22                 return '%s' %self.y
23         except:
24             return 'There is no this item in class Point'
25 
26     def __delitem__(self, key):
27         del self.__dict__[key]
28 
29 if __name__ == '__main__':
30     p = Point()
31     p['x'] = 3
32     print(p['x'])
33     p['y'] = 6
34     print(p)
35     del p['x']
36     print(p['x'])

运行结果

1 Called the __setitem__ function
2 Called the __getitem__ function
3 3
4 Called the __setitem__ function
5 Point is (3,6)
6 Called the __getitem__ function
7 There is no this item in class Point
8 
9 Process finished with exit code 0

 

 




扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄