封装指的是将对象的状态信息隐藏在对象内部,不允许外部直接访问对象内部信息,而是通过该类提供的方法来实现对内部信息的操作和访问;封装的含义,实际上,是把该隐藏的隐藏起来,该暴露的暴露出来;Python只需要将类的成员名为以双下划线开头,就可以隐藏类中的成员。
一、封装数据属性
例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
class Fraction: __grade = 0 def __init__( self ,name): self .__name = name def setting_grade( self ,var): if isinstance (var, int ) and var > = 0 and var < = 100 : Fraction.__grade = var else : print ( '请输入正确的分数!' ) def setting_name( self ,set_name): if isinstance (set_name, str ): self .__name = set_name else : print ( '请输入正确的姓名!' ) def get_fraction( self ): print ( '%s分数是:%s' % ( self .__name,Fraction.__grade)) F = Fraction( '小黄' ) print (F.__grade) # 报错 AttributeError: 'Fraction' object has no attribute '__grade' print (F.__name) # 报错 AttributeError: 'Fraction' object has no attribute '__name' F.get_fraction() # 打印 小黄分数是:0 F.setting_name( '小明' ) F.setting_grade( 100 ) # setting_grade()、setting_name()会对用户设置grade、name进行控制,符合条件才能允许设置 F.get_fraction() # 打印 小明分数是:100 # 可以使用 _类名来访问或修改对象的实例变量 print (F._Fraction__grade) # 打印 100 print (F._Fraction__name) # 打印 小明 |
上面例子中,代码print (F.__grade)和print (F.__name)直接访问私有变量会报错setting_grade()、setting_name()方法用于对grade、name进行设置,只有符合条件才能允许设置;print (F._Fraction__grade)和print (F._Fraction__name)通过 _类名来访问对象的实例变量(通常不要这么做),可以看出Python并没有实现真正隐藏,只是改变以双下划线开头的变量,在这些变量前添加单下画线和变量名。
二、封装函数属性
例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
class SumFraction: def __init__( self ,usually,test): self .__usually = usually self .__test = test def set_usually_score( self ,usually_var): if isinstance (usually_var, int ) and usually_var > = 0 and usually_var < = 100 : self .__usually = usually_var else : print ( '请输入正确的分数!' ) def set_test_score( self ,test_var): if isinstance (test_var, int ) and test_var > = 0 and test_var < = 100 : self .__test = test_var else : print ( '请输入正确的分数!' ) def __calculation( self ): # 私有方法,只能内部使用,对外部隐藏运算逻辑 return self .__usually * 0.3 + self .__test * 0.7 def final_grade( self ): return self .__calculation() S = SumFraction( 100 , 50 ) print (S.final_grade()) # 打印 65.0 print (S.__calculation()) # 调用隐藏的__calculation()方法,会报错 AttributeError: 'SumFraction' object has no attribute '__calculation' print (S._SumFraction__calculation()) # 可以使用_类名方法名调用(不推荐这样做),打印 65.0 # 修改__usually和__test S.set_usually_score( 70 ) S.set_test_score( 100 ) print (S.final_grade()) # 通过final_grade()方法内部进行访问__calculation()私有方法,打印 91.0 |
上面代码中,set_usually_score()和set_test_score()用于对usually 、test进行设置;__calculation()是私有方法,默认是隐藏的,只允许内部使用,外部使用会报错,当然也可以使用_类名方法名调用,但并不推荐这么做;print (S.final_grade())通过final_grade()方法内部访问__calculation()私有方法。
三、property
先看一下帮助文档:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
>>> help ( property ) Help on class property in module builtins: class property ( object ) | property (fget = None , fset = None , fdel = None , doc = None ) | | Property attribute. | | fget | function to be used for getting an attribute value | fset | function to be used for setting an attribute value | fdel | function to be used for del 'ing an attribute | doc | docstring | | Typical use is to define a managed attribute x: | | class C( object ): | def getx( self ): return self ._x | def setx( self , value): self ._x = value | def delx( self ): del self ._x | x = property (getx, setx, delx, "I'm the 'x' property." ) | | Decorators make defining new properties or modifying existing ones easy: | | class C( object ): | @ property | def x( self ): | "I am the 'x' property." | return self ._x | @x.setter | def x( self , value): | self ._x = value | @x.deleter | def x( self ): | del self ._x | | Methods defined here: | | __delete__( self , instance, / ) | Delete an attribute of instance. | | __get__( self , instance, owner, / ) | Return an attribute of instance, which is of type owner. | | __getattribute__( self , name, / ) | Return getattr ( self , name). | | __init__( self , / , * args, * * kwargs) | Initialize self . See help ( type ( self )) for accurate signature. | | __set__( self , instance, value, / ) | Set an attribute of instance to value. | | deleter(...) | Descriptor to change the deleter on a property . | | getter(...) | Descriptor to change the getter on a property . | | setter(...) | Descriptor to change the setter on a property . | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Static methods defined here: | | __new__( * args, * * kwargs) from builtins. type | Create and return a new object . See help ( type ) for accurate signature. | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Data descriptors defined here: | | __isabstractmethod__ | | fdel | | fget | | fset |
@property 可以在一个类中把方法变成同名属性调用,能用属性的方式来访问该属性。
@x.setter 表示可写,最大作用是用于限制属性的定义,x是被@property修饰的方法名,@x.setter修饰的方法名@property修饰的方法名必须同名。
@x.deleter 表示可删除,x是被@property修饰的方法名,@x.deleter修饰的方法名@property修饰的方法名必须同名。
例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
class SumFraction: def __init__( self ,value): self .__score = value @property # 读 def score( self ): print ( '读......' ) return self .__score @score .setter # 写 def score( self ,var): print ( '写......' ) if isinstance (var, int ) and var > = 0 and var < = 100 : self .__score = var return self .__score else : print ( '请输入正确的分数!' ) return @score .deleter # 删除 def score( self ): print ( "删除self.__score......" ) del self .__score S = SumFraction( 100 ) S.score = 80 # 写,打印 改...... print (S.score) ''' 读,打印 读...... 80 ''' del S.score # 删除,打印 删除self.__score...... print (S.score) # __score已被删除,打印 AttributeError: 'SumFraction' object has no attribute '_SumFraction__score' |
用property类来实现,例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
class SumFraction: def __init__( self ,value): self .__score = value def get_score( self ): print ( '读......' ) return self .__score def set_score( self ,var): print ( '写......' ) if isinstance (var, int ) and var > = 0 and var < = 100 : self .__score = var return self .__score else : print ( '请输入正确的分数!' ) return def del_score( self ): print ( "删除self.__score......" ) del self .__score score = property (get_score,set_score,del_score, '这里是属性含义~ ' ) S = SumFraction( 100 ) S.score = 80 # 写,打印 改...... print (S.score) ''' 读,打印 读...... 80 ''' print (SumFraction.score.__doc__) # 属性含义,打印 这里是属性含义~ del S.score # 删除,打印 删除self.__score...... print (S.score) # __score已被删除,打印 AttributeError: 'SumFraction' object has no attribute '_SumFraction__score' |