python3 多态,(浅谈)封装,反射,内置的__xxxattr方法
1 class Cube():
2 def __init__(self,width,length,high,name):
3 self.__width=width
4 self.__length=length
5 self.__high=high
6 self.__name=name
7
8
9 def volume(self):
10 ti_ji=self.__high*self.__length*self.__width
11 return ti_ji
12
13 def getName(self):
14 return self.__name
15
16 C1=Cube(100,100,100,"小周周")
17 print(C1.volume())
18 print(C1.getName())
19
20 #####
21 1000000
22 小周周
1.类的多态:
由不同的类实例化得到的对象,调用同一个方法,执行的逻辑不同。
继承和多态的关系:
继承和多态可以说是相辅相成的,继承实现了代码的重用,但是必须要有一个机制来吧重用的代码用起来,那这个机制就是多态。
1 class Num():
2 def __init__(self,name):
3 self.name=name
4
5 def aaa(self):
6 number=input('请输入一个数字>>>>>>>>:')
7 i=int(number)
8 if i<60:
9 print("%s 成绩不及格" %self.name)
10 if 60<=i<=80 :
11 print("%s 成绩良好" %self.name)
12 if 80<i<=99:
13 print("%s 那你很优秀喔" %self.name)
14 if i==100:
15 print("%s 满分" %self.name)
16
17 class one(Num):#####继承
18 pass
19 class two(Num):#####继承
20 pass
21 class three(Num):#####继承
22 pass
23 #########不同的类实例化得到对象调用同一个方法
24 L1=one("小周周")
25 L1.aaa()
26 L2=two("小周周")
27 L2.aaa()
28 L3=three("小周周")
29 L3.aaa()
30
31 ############
32 请输入一个数字>>>>>>>>:78
33 小周周 成绩良好
34 请输入一个数字>>>>>>>>:56
35 小周周 成绩不及格
36 请输入一个数字>>>>>>>>:100
37 小周周 满分
python中的标准类型就是多态概念的一个很好的示范。
2.类的封装:
封装就是隐藏的意思,对类来说,类用属性字典来装。
最大的误区,封装就是把属性隐藏起来,外部不能访问。那这样就是没有考虑到封装的本质就是要给用户使用,明确区分内外,内部实现的逻辑,
外部调用者无法知晓,但是类要提供一个可以访问到内部逻辑的方法给外部使用,所以说呢,是不可能完成真正的封装的。
在python中是通过约定来实现封装,使用下划线或者双下划綫开头的属性都是类私有的,外部不能访问。
1 class Cube():
2 def __init__(self,width,length,high,name):
3 self.__width=width
4 self.__length=length
5 self.__high=high
6 self.__name=name
7
8
9 def volume(self):
10 ti_ji=self.__high*self.__length*self.__width
11 return "体积是: ",ti_ji
12
13 def getName(self):
14 return self.__name
15
16 C1=Cube(100,100,100,"小周周")
17 print(C1.volume())
18 print(C1.getName())
19
20
21 ########
22 ('体积是: ', 1000000)
23 小周周
3.反省
在计算机编程中,自省是指这种能力:检查某些事物以确定它是什么、它知道什么以及它能做什么。自省向程序员提供了极大的灵活性和控制力。
(1)hasattr()函数用于判断是否包含对应的属性
语法:hasattr(object,name)
参数:object--对象;
name--字符串,属性名
返回值: 如果对象有该属性返回True,否则返回False
(2)getattr()函数用于返回一个对象属性值
语法:getattr(object,name,default)
参数:
object--对象
name--字符串,对象属性
default--默认返回值,如果不提供该参数,在没有对于属性时,将触发AttributeError。
返回值:返回对象属性值
(3)
setattr函数,用于设置属性值,该属性必须存在
语法:setattr(object,name,value)
参数:
object--对象
name--字符串,对象属性
value--属性值
返回值:无
(4)
delattr函数用于删除属性
delattr(x,'foobar)相当于del x.foobar
语法:setattr(object,name)
参数:
object--对象
name--必须是对象的属性
返回值:无
1 #反射
2 class Person():
3 def __init__(self,name,addr):
4 self.name=name
5 self.addr=addr
6 def play(self,ball):
7 print("%s 在 %s %s" %(self.name,self.addr,ball))
8 p=Person("小周周","成信大操场")
9 ###hasattr判断object中有没有一个相对应的字符串对应的方法或属性
10 print(hasattr(p,"name"))
11 print(hasattr(p,"play"))
12 print(hasattr(p,"assd"))
13
14 print(getattr(p,"name"))
15 func=getattr(p,"play")
16 func("打篮球")
17 print(getattr(p,"play"))#没有则报错
18 print(getattr(p,"playq","啦啦啦啦,被我打败了"))#没有不会报错,输出后面默认的
19
20 ####添加
21 setattr(p,"sb","小周周")
22 setattr(p,"age",18)
23 setattr(p,'func',lambda x:x+1)
24 setattr(p,'func1',lambda self:self.name+'sb')
25 print(p.__dict__)
26 print(p.func(10))
27 print(p.func1(p))
28
29 delattr(p,"name")
30 print(p.__dict__)
31
32 ###############
33 True
34 True
35 False
36 小周周
37 小周周 在 成信大操场 打篮球
38 <bound method Person.play of <__main__.Person object at 0x0000000002C6DE80>>
39 啦啦啦啦,被我打败了
40 {'age': 18, 'sb': '小周周', 'name': '小周周', 'func1': <function <lambda> at 0x0000000002C6FB70>, 'addr': '成信大操场', 'func': <function <lambda> at 0x0000000002C6F950>}
41 11
42 小周周sb
43 {'age': 18, 'sb': '小周周', 'func1': <function <lambda> at 0x0000000002C6FB70>, 'addr': '成信大操场', 'func': <function <lambda> at 0x0000000002C6F950>}
4.双下划綫开头的attr方法:
(1)__getattr__,
只有在属性不存在时,会自动触发__getattr__
1 class Person():
2 def __init__(self,name):
3 self.name=name
4 def __getattr__(self, item):
5 print('>>>>>>>>>>>>>>>属性%s不存在' %item)
6 p=Person("小周周")
7 print(p.name)
8 print(p.age)
9
10 ############
11 小周周
12 >>>>>>>>>>属性age不存在
13 None
(2)__setattr__
系统默认的__setattr__,会将传入的值自动设置为字典
1 class Person():
2 def __init__(self,name):
3 self.name=name
4
5 p=Person("小周周")
6 print(p.__dict__)
7 #####################
8 {'name': '小周周'}
重写了之后:啥也不干了,会去出发重写的__setattr__方法
实例化也会出发其执行(why?呵呵,底层就是这样实现的)
1 class Person():
2 def __init__(self,name):
3 self.name=name
4 def __setattr__(self, key, value):
5 print('key=啥,value=啥>>>>>>>>>>>>>>>',key,value)
6
7 p=Person("小周周")
8 print(p.__dict__)
9
10
11 ###############
12 key=啥,value=啥>>>>>>>>>>>>>>> name 小周周
13 {}
添加新的属性后:
1 class Person():
2 def __init__(self,name):
3 self.name=name
4 def __setattr__(self, key, value):
5 print('key=啥,value=啥>>>>>>>>>>>>>>>',key,value)
6
7 p=Person("小周周")
8 print(p.__dict__)
9 p.age=18
10 print(p.__dict__)
11
12 ###########
13 key=啥,value=啥>>>>>>>>>>>>>>> name 小周周
14 {}
15 key=啥,value=啥>>>>>>>>>>>>>>> age 18
16 {}
一段小小的代码:(可以实现一种定制的赶脚)
1 class Person():
2 def __init__(self,name):
3 self.name=name
4 def __setattr__(self, key, value):
5 if type(value) is str:
6 self.__dict__[key]=value
7 else:
8 print("小伙子,请输入字符串类型的")
9
10
11 p=Person("Jack")
12 print(p.__dict__)
13 p.gender="male"
14 p.age=18
15 print(p.__dict__)
16
17 ######################
18 {'name': 'Jack'}
19 小伙子,请输入字符串类型的
20 {'name': 'Jack', 'gender': 'male'}
(3)__delattr__(赶脚有点神奇)
1 class Person():
2 def __init__(self,name):
3 self.name=name
4 def __setattr__(self, key, value):
5 if type(value) is str:
6 self.__dict__[key]=value
7 else:
8 print("小伙子,请输入字符串类型的")
9 def __delattr__(self, item):
10 print('不允许删除属性【%s】' %item)
11 print("删除没有成功")
12
13 p=Person("Jack")
14 print(p.__dict__)
15 p.gender="male"
16 p.age=18
17 print(p.__dict__)
18 del p.name
19 print(p.__dict__)
20
21 ###################
22 {'name': 'Jack'}
23 小伙子,请输入字符串类型的
24 {'gender': 'male', 'name': 'Jack'}
25 不允许删除属性【name】
26 删除没有成功
27 {'gender': 'male', 'name': 'Jack'}
1 class Person():
2 def __init__(self,name):
3 self.name=name
4 def __setattr__(self, key, value):
5 if type(value) is str:
6 self.__dict__[key]=value
7 else:
8 print("小伙子,请输入字符串类型的")
9 def __delattr__(self, item):
10 self.__dict__.pop(item)
11
12 p=Person("Jack")
13 print(p.__dict__)
14 p.gender="male"
15 p.age=18
16 print(p.__dict__)
17 del p.name
18 print(p.__dict__)
19
20 ##############
21 {'name': 'Jack'}
22 小伙子,请输入字符串类型的
23 {'name': 'Jack', 'gender': 'male'}
24 {'gender': 'male'}


浙公网安备 33010602011771号