面向对象-魔术方法-属性相关

属性相关的魔术方法:
就是获取成员,删除成员,修改成员相关联的魔术方法而已

5个与属性相关的魔术方法

1.__getattr__
2.__setattr__
3.__delattr__
4.__getattribute__
5.__dir__


属性访问的顺序!

1.调用__getattribute__
2.【调用数据描述符】
3.调用当前对象的所属成员
4.调用类的所属成员
5.【调用非数据描述符】
6.调用父类的所属成员
7.调用__getattr__

注意:以上步骤是调用某个成员的访问顺序及优先级。前面的能获取成员,就不会向后查找


1.__getattribute__
触发时机:访问对象成员的时候就会触发,无论成员是否存在
作用:可以在用户获取数据的时候进行数据处理等操作
参数:一个self接受当前对象,另外一个参数接受访问对象成员名称的字符串
返回值:有 不设定返回None
注意事项:在当前魔术方法中禁止使用 当前对象.成员 的方式访问成员,会触发递归操作,必须借助object的__getattribute__来获取当前对象的成员

 1 #__getattribute__属性魔术方法
 2 class Human:
 3     #添加成员属性(离开入对象)
 4     def __init__(self):
 5         self.name ='里斯'
 6         self.sex = ""
 7         self.age = 18
 8 
 9     #添加魔术方法
10     def __getattribute__(self,item):
11         print("getattribute方法被触发")
12 
13         #如果用当前 self.item 获取的话就回触发自已,导致最大深度的递归错误
14         #所以用最顶层的 object.__getattribute(self,item)来获取
15         #item参数可以是任意变量,item参数就是获取,对象.属性-item实参
16         var = object.__getattribute__(self,item)
17         var2 = var[0] + '*' + var[-1]
18         return var2
19 
20     #添加成员方法
21     def eat(self):
22         print('一天三次小烧烤')
23 
24     def drink(self):
25         print('喝啤酒')
26 
27 #实例化对象
28 ls = Human()
29 #打印对象
30 print(ls)
31 
32 #打印对象的属性,触发__getattribute__的方法存
33 #print(ls.name2)
34 #输出结果:AttributeError: 'Human' object has no attribute 'name2'
35 
36 print(ls.name)
37 '''
38 输出结果:
39 getattribute方法被触发
40 里*斯
41 '''

 

2.__getattr__
触发时机:访问不存在的对象成员的时候自动触发
作用:防止访问不存在成员的时候报错!为不存在的成员定义值
参数:一个self接受当前对象,第二个参数接受访问成员的名称字符串
返回值:可有可无
注意事项:

 1 #__getattr__属性魔术方法
 2 class Human:
 3     #添加成员属性(离开入对象)
 4     def __init__(self):
 5         self.name ='里斯'
 6         self.sex = ""
 7         self.age = 18
 8         self.err = '没有这个名字'
 9 
10     #__getattr__访问不存在的属性时触发,
11     def __getattr__(self,item): #item参数可以是任意变量,item参数就是获取,对象.属性-item实参
12         print('getattr被触发')
13         item = self.err
14         return item
15     #添加成员方法
16     def eat(self):
17         print('一天三次小烧烤')
18 
19     def drink(self):
20         print('喝啤酒')
21 
22 #实例化对象
23 ls = Human()
24 #打印对象
25 print(ls)
26 #输出结果:<__main__.Human object at 0x000001DA5A292BE0>
27 
28 print(ls.name2)
29 '''
30 输出结果:
31 getattr被触发
32 没有这个名字
33 '''

 

3.__setattr__
触发时机:添加对象成员或者修改对象成员的时候自动触发!
作用:可以限制或者管理对象成员的添加与修改操作
参数:一个self接受当前对象 第二个接受设置的成员名称字符串 第三个设置的值
返回值:
注意事项:在当前魔术方法中禁止使用当前对象.成员名 = 值的方式,会触发递归cao'zuo !

 1 #__setattr__属性魔术方法
 2 class Human:
 3     #sex属在在类设置,因为一但触发__setattr__修改属性方法,就会被清空,连添加都不可以
 4     #所在sex在类设置就不会被清空
 5     sex = ""
 6     #添加成员属性(离开入对象)
 7     def __init__(self):
 8         self.name ='里斯'
 9 
10         self.age = 18
11         self.err = '没有这个名字'
12 
13     #__setattr__访问不存在的属性时触发,
14     def __setattr__(self,a,b):#须要在self,后面添加两个参数 a = 成员属性(例:name),b = 修改后的值
15         #1.相当于在重载object的__setattr__,如第2项重载回object的操作相当恢复默认
16         # 2.object.__setattr__(self,a,b)
17         #print('setattr被触发' + str(a) + str(b))
18 
19         #1.禁止修改性别,1.修改名称最多使用三个字符多余的舍弃
20         if a == 'sex':
21             pass
22         else:
23             object.__setattr__(self,a,b)
24 
25     #添加成员方法
26     def eat(self):
27         print('一天三次小烧烤')
28 
29     def drink(self):
30         print('喝啤酒')
31 
32 #实例化对象
33 ls = Human()
34 #打印对象
35 print(ls)
36 #输出结果:<__main__.Human object at 0x0000023932572BE0>
37 
38 print(ls.__dict__)
39 #输出结果:{'name': '里斯', 'age': 18, 'err': '没有这个名字'}
40 ls.name = '老里'
41 print(ls.__dict__)
42 #输出结果:{'name': '老里', 'age': 18, 'err': '没有这个名字'}
43 
44 print(ls.sex)
45 #输出结果:男
46 ls.sex = '' #被__setattr__设置禁止修改性别
47 print(ls.sex)
48 #输出结果:男
49 
50 #没有设置__setattr__方法的修改成员属性及输出如下
51 #print(ls.__dict__)
52 #输出结果:{'name': '里斯', 'sex': '男', 'age': 18, 'err': '没有这个名字'}
53 #ls.name = '老里'
54 #print(ls.__dict__)
55 #输出结果:{'name': '老里', 'sex': '男', 'age': 18, 'err': '没有这个名字'}

 

4.__delattr__
触发时机:删除对象成员的时候自动触发
作用:可以限制对象成员的删除
参数:一个self接受当前对象,另外一个接受删除的成员属性名称的字符串
返回值:
注意事项:如果要删除对象成员,要借助object中的__delattr__来操作。

5.__dir__
触发时机:使用dir函数操作对象的时候自动触发
作用:
参数:一个self接受当前对象
返回值:有,必须是容器类数据
注意事项:

 

posted @ 2019-05-14 13:32  双伟科技  阅读(158)  评论(0编辑  收藏  举报