面向对象中的方法
# 面向对象中的方法
和类属性一样,类方法也可以进行更细致的划分,具体可分为实例方法、类方法、静态方法、私有方法、魔法方法。
# 实例方法
定义:第一个参数必须是实例对象,该参数名一般约定为“self”,通过它来传递实例的属性和方法(也可以传类的属性和方法);
调用:只能由实例对象调用。
class CLanguage:
#类构造方法,也属于实例方法
def __init__(self):
self.name = "C语言中文网"
self.add = "http://c.biancheng.net"
# 下面定义了一个say实例方法
def say(self):
print("正在调用 say() 实例方法")
clang = CLanguage()
clang.say() # 正在调用 say() 实例方法
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
当然,Python 也支持使用类名调用实例方法,但此方式需要手动给 self 参数传值。例如:
#类名调用实例方法,需手动给 self 参数传值
clang = CLanguage()
CLanguage.say(clang) # 正在调用 say() 实例方法
# 通过手动将 clang 这个类对象传给了 self 参数,使得程序得以正确执行。实际上,这里调用实例方法的形式完全是等价于 clang.info()。
1
2
3
4
5
2
3
4
5
# 类方法
Python 类方法和实例方法相似,它最少也要包含一个参数,只不过类方法中通常将其命名为 cls,Python 会自动将类本身绑定给 cls 参数(注意,绑定的不是类对象)。也就是说,我们在调用类方法时,无需显式为 cls 参数传参。
调用:实例对象和类对象都可以调用。
@classmethod
def 名称(cls, a="dfg"): # 类方法,需要定义@classmethod,类方法的参数为cls
pass
1
2
3
2
3
特点:
- 定义需要依赖装饰器@classmethod
- 类方法中参数不是一个对象,而是类 cls
- 类方法中只可以使用类属性
- 类方法中可以使用类中的普通方法,不过要先创建实例调用 cls().show()
类方法的作用:
- 只能访问类属性和类方法,所以可以在对象创建之前,如果需要完成一些动作(功能)
"""
特点:
- 定义需要依赖装饰器@classmethod
- 类方法中参数不是一个对象,而是类 cls
- 类方法中只可以使用类属性
- 类方法中可以使用类中的普通方法,不过要先创建实例调用 cls().show()
类方法的作用:
- 只能访问类属性和类方法,所以可以在对象创建之前,如果需要完成一些动作(功能)
"""
class Dog:
a = "abc" # 类属性
def __init__(self, name): # 初始化方法
self.name = name
def run(self):
print("{}在跑".format(self.name))
def eat(self): # 普通方法的参数为self
Dog.show() #
print("{}在吃东西".format(self.name))
self.run() # 调用类中的普通方法
@classmethod
def show(cls, a="dfg"): # 类方法,需要定义@classmethod,类方法的参数为cls
print("我是类方法{}".format(a))
print(cls) # <class '__main__.Dog'>
@classmethod # 只能访问类属性和类方法 调用类方法是用cls.类方法名()
def show1(cls, b="abc"):
print("我是类方法2{}".format(b))
cls.show() # 在类方法中调用类方法
cls("类方法-->").eat() # 修改普通方法的传参
c = Dog("小花")
# c.run() # 普通方法
c.eat() # 普通方法中调用类方法
# print(c.a) # 获取类中的属性
c.show1() # 类方法调用普通方法
"""
我是类方法dfg
<class '__main__.Dog'>
小花在吃东西
小花在跑
我是类方法2abc
我是类方法dfg
<class '__main__.Dog'>
我是类方法dfg
<class '__main__.Dog'>
类方法-->在吃东西
类方法-->在跑
进程已结束,退出代码为 0
"""
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
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
# 通过类方法修改私有变量
# 通过类方法修改私有变量
class Person:
__age = 18
def show(self):
print("--->", Person.__age)
@classmethod
def update_age(cls):
cls.__age = 200 # 用类方法修改私有属性
print("我是修改的类方法")
@classmethod
def show_age(cls):
print("我是修改后的类方法", cls.__age)
cls().show()
a = Person()
a.show()
a.update_age()
a.show_age()
"""
---> 18
我是修改的类方法
我是修改后的类方法 200
---> 200
"""
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
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
# 静态方法
静态方法,其实就是我们学过的函数,和函数唯一的区别是,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中。
静态方法没有类似 self、cls 这样的特殊参数,因此 Python 解释器不会对它包含的参数做任何类或对象的绑定。也正因为如此,类的静态方法中无法调用任何类属性和类方法,静态方法可以调用没有self的普通方法,可以调用类方法
调用:类.方法名 和 实例化调用 。
"""
类的静态方法中无法调用任何类实例属性和类实例方法(有self),`静态方法可以调用没有self的普通方法、类方法、类属性`**
**调用:类.方法名 和 实例化调用 。**
"""
class Person:
__age = 18
def show(self):
print("--->", Person.__age)
def show1():
print("123456676767867")
@classmethod
def update_age(cls):
cls.__age = 200 # 用类方法修改私有属性
print("我是修改的类方法")
@classmethod
def show_age(cls):
cls.update_age()
print("我是修改后的类方法", cls.__age)
@staticmethod
def test():
print("我是静态方法")
Person.show_age() # 静态方法可以调用类方法
# Person.show() #静态方法不能调用里面有self的普通方法 但是可以通过在里面创建类的实例进行调用 Person().show()
# Person().show()
Person.show1() # 里面没有self的就可以调用
s = Person.__age
print("我是调用的类属性", s)
a = Person()
a.test()
"""
我是静态方法
我是修改的类方法
我是修改后的类方法 200
123456676767867
我是调用的类属性 200
"""
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
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
# 私有方法
方法:
公有方法:对象可以访问;类内部可以访问;派生类中可以访问
私有方法:仅类内部可以访问;
"""
公有方法:对象可以访问;类内部可以访问;派生类中可以访问
私有方法:仅类内部可以访问;
"""
class C:
def __init__(self):
pass
def __add(self):
print('in C')
class D(C):
def __show(self):
print('in D')
def func(self):
self.__show()
obj = D()
# obj.__show() # 通过不能对象访问 AttributeError: 'D' object has no attribute '__show'
obj.func() # 通过类内部函数可以访问到私有方法
# obj.__add() # 派生类中不能访问
"""
in D
"""
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
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
# 魔法方法
编辑 (opens new window)
上次更新: 2023/05/17, 23:08:21