1方法重载
1.1 Python不支持方法重载
在强类型语言(比如:C语言、Java语言)中,可以定义多个重名的方法,只要保证方法的签名唯一即可。方法签名包含三个部分:
- 方法名
- 参数数目
- 参数类型
Python中,方法的参数没有声明类型(调用时才能确定参数的类型),参数的数目也可以由可变参数控制。因此,python中没有方法的重载。定义一个方法既可以有多种调用方式,相当于实现了其他语言中的方法的重载。
但是这种方式,相对强类型语言,可能没有那么直观,因为要在一个函数里面处理多种情况。
如果我们在类体中定义了多个重名的方法,只有最后一个方法有效。
建议:不要使用重名的方法
1.2 代码说明
示例代码:
class Person:
def say_hi(self):
print("hello")
def say_hi(self, name):
print("{0},hello".format(name))
p1 = Person()
p1.say_hi("niefajun")
print("--" * 20)
p1.say_hi()
运行结果:
niefajun,hello
----------------------------------------
Traceback (most recent call last):
File "test.py", line 13, in <module>
p1.say_hi()
TypeError: say_hi() missing 1 required positional argument: 'name'
程序说明:
在类Person定义了两个方法,但是两个方法同名,都是say_hi
,按照前面的解释,只有最后一个生效,那么就等效于只定义了say_hi(self, name)
这一个方法。第一次采用p1.say_hi("niefajun")
这种方式调用,和参数能够对应,所以可以正常输出内容。第二次采用p1.say_hi()
,没有参数,相当于缺少一个参数,所以提示错误信息:TypeError: say_hi() missing 1 required positional argument: 'name'
2方法的动态性
python是动态语言,我们可以动态的为类添加新的方法,或者动态的修改类的已有的方法。
2.1代码说明
示例代码:
# 定义一个独立的普通方法
def play_game(self):
print("玩游戏休息一会")
class Person:
def __init__(self, name):
self.name = name
def work(self):
print("努力工作")
Person.play = play_game
p1 = Person("p1")
p1.work()
p1.play()
运行结果:
努力工作
玩游戏休息一会
程序说明:
对象p1是类Person的实例,虽然在Person类声明中只定义了work
一个方法,但是后面通过动态赋值的方法,增加了一个play
属性,指向函数play_game
,实际就是增加了一个play
的实例方法。所以后面执行p1.work()
和p1.play()
都能输出正确的结果。
说明:虽然通过方法动态性可以动态的添加方法,但是在实际开发中不建议这样做,这样会导致代码可读性下降,存在潜在风险。
3.__slots__
类变量限制动态性
Python中可以很方便的实现属性、方法的动态性,使用起来很方便,但是也会造成一定的不确定性,所以在Python中使用__slots__
属性来限制属性和方法动态性。
示例代码:
class Person:
"""使用__slots__限制Person只允许添加name一个属性"""
__slots__ = ('name',)
def __init__(self, name):
self.name = name
p1 = Person("聂发俊")
print(p1.name)
print("--" * 20)
p1.age = 100
print(p1.age)
运行结果:
聂发俊
----------------------------------------
Traceback (most recent call last):
File "test.py", line 12, in <module>
p1.age = 100
AttributeError: 'Person' object has no attribute 'age'
程序说明:
在定义Person
类的时候,使用了__slots__
属性,限定属性只有name
一个字段,不允许动态添加其他字段。程序运行,前面正常实例化对象p1,并打印p1.name
属性,结果是正常的。后面动态复制age
属性为100,因为__slots__
的限定,无法动态添加属性,所以提示错误信息:AttributeError: 'Person' object has no attribute 'age'
.
备注:
更多精彩博客,请访问:聂发俊的技术博客
对应视频教程,请访问:python400
完整markdown笔记,请访问: python400_learn_github