上一篇学习了Python面向对象的3大特性,封装,继承和多态,这一篇继续学习类成员,包括字段,方法,属性以及他们的修饰符。
1.字段
字段分为静态字段和普通字段。静态字段属于类,而普通字段属于对象,因此静态字段在内存中只保存一份,而普通字段在每个对象中都保存了一份。定义的时候静态字段定义在类的范围里面,而普通字段定义在方法里面。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
>>>
class
Foo:
# 字段(静态字段)
CC
=
123
def
__init__(
self
):
# 字段(普通的字段)
self
.name
=
'alex'
def
show(
self
):
print
(
self
.name)
obj
=
Foo()
print
(obj.name)
print
(Foo.CC)
print
(obj.CC)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
alex
123
123
|
注意上面,尽管我们通过对象也能调用静态字段,这种方式应该尽量避免!
2.方法
方法包括静态方法,普通方法和类方法。
静态方法:由类调用,无默认参数;
普通方法:由对象调用,至少一个self参数,执行的时候,自动把对象赋值给self
类方法:由类调用,至少一个cls参数,执行的时候,自动将该方法的类赋值给cls
例如:
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
|
class
Province:
#静态字段
country
=
"中国"
def
__init__(
self
,name):
self
.name
=
name
# 普通方法,由对象去调用执行(方法属于类)
def
show(
self
):
# print(self.name)
print
(
123
)
@
staticmethod
def
f1(cla,a1,a2):
# 静态方法,由类调用执行。(当方法内部不需要对象中封装的值时,可以将方法写成静态方法)
print
(a1,a2)
@
classmethod
def
f2(
cls
):
# class
cls
# 类名,()创建对象
# cls()
print
(
cls
)
def
f3(
self
):
return
self
.name[
1
]
obj
=
Province(
"河南"
)
obj.show()
Province.f1(Province,
1
,
2
)
Province.f2()
obj
=
Province(
'alex'
)
ret
=
obj.f3()
print
(ret)
-
-
-
-
-
-
-
-
-
-
-
-
-
123
1
2
<
class
'__main__.Province'
>
l
|
3.属性
属性的本质就是一个方法,不过我们通过调用字段的方式去调用他。字段可以调用a=obj.name,可以赋值obj.name='alex',可以删除del obj.name,属性自然也需要实现这些功能
属性有2种方式来定义:装饰器方式或者静态字段的方式
首先看看装饰器方式,分别在普通方法上面添加@property, @xx.settler @xx.deleter就能实现了,当我们调用,赋值,和删除的时候他会自动调用对应的方法
例如
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
|
class
Foo:
def
func(
self
):
pass
# 定义属性
@
property
def
prop(
self
):
print
(
'property'
)
@prop.setter
def
prop(
self
,value):
print
(
"settle"
)
@prop.deleter
def
prop(
self
):
print
(
"deletter"
)
# ############### 调用 ###############
foo_obj
=
Foo()
foo_obj.func()
foo_obj.prop
foo_obj.prop
=
200
del
foo_obj.prop
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
property
settle
deletter
|
第二种方式是通过静态字段的方式
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
|
class
Pager:
def
__init__(
self
, all_count):
self
.all_count
=
all_count
def
f1(
self
):
return
123
def
f2(
self
,value):
print
(
'setup'
)
def
f3(
self
):
print
(
'del'
)
foo
=
property
(fget
=
f1,fset
=
f2, fdel
=
f3)
p
=
Pager(
101
)
result
=
p.foo
print
(result)
p.foo
=
"alex"
del
p.foo
-
-
-
-
-
-
-
-
-
-
-
-
-
123
setup
del
|
-
第一个参数是方法名,调用
对象.属性
时自动触发执行方法 -
第二个参数是方法名,调用
对象.属性 = XXX
时自动触发执行方法 -
第三个参数是方法名,调用
del 对象.属性
时自动触发执行方法 -
第四个参数是字符串,调用
对象.属性.__doc__
,此参数是该属性的描述信息
4.修饰符
所有的类成员都有两种形式
公有成员:任何地方都能访问
私有成员:只有类的内部可以访问
命名形式很简单,就是前两个字符是下划线__(注意和特殊成员区分开)
静态字段
-
公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
-
私有静态字段:仅类内部可以访问;
例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class
C:
name
=
"公有静态字段"
def
func(
self
):
print
(C.name)
class
D(C):
def
show(
self
):
print
(C.name)
print
(C.name)
# 类访问
obj
=
C()
obj.func()
# 类内部可以访问
obj_son
=
D()
obj_son.show()
# 派生类中可以访问
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
公有静态字段
公有静态字段
公有静态字段
|
如果改成私有静态字段,那么类不可以访问,派生类也不可以访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class
C:
__name
=
"私有静态字段"
def
func(
self
):
print
(C.__name)
class
D(C):
def
show(
self
):
print
(C.__name)
# print(C.__name) # 类无法访问
obj
=
C()
obj.func()
# 类内部可以访问
obj_son
=
D()
# obj_son.show() # 派生类中不可以访问
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
私有静态字段
|
普通字段
-
公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问
-
私有普通字段:仅类内部可以访问;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class
C:
def
__init__(
self
):
self
.__foo
=
"私有普通字段"
def
func(
self
):
print
(
self
.__foo)
class
D(C):
def
show(
self
):
print
(
self
.__foo)
obj
=
C()
# obj.__foo # 通过对象访问 ==> 错误
obj.func()
# 类内部访问 ==> 正确
obj_son
=
D();
# obj_son.show() # 派生类中访问 ==> 错误
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
私有字段
|
方法和属性的访问方式和上面相似。