读书笔记——python的多态

2023-01-10 15:08:29

摘写自《python学习手册》第16章 函数基础

引言

函数的定义与调用

定义

def times(x,y):
	return x*y

上面的代码定义了一个名为times的函数,该函数将返回它的两个参数的乘积。

调用
def语句创建了一个函数但是没有执行它。在def运行之后,可以在程序中通过在函数名后面增加括号调用这个函数。括号中包含n个对象参数,这些参数汇传递(赋值)给函数头部的形式参数名:

>>times(2,4)
8

在这里插入图片描述
第二次调用传递了两个完全不同种类的对象。如上图。
这次函数的作用完全不同。第二次调用将一个字符串和一个整数传递给x,y,而不是两个数字。回顾一下,*对数字和序列都有效。因为在python中,从未对变量、参数或者返回值有过类型的声明,所以我们既可以把times作为数字的乘法,又可以用作序列的重复。
换句话说,函数times的作用取决于传递给它的值。这是python中的核心概念之一(也是使用python的诀窍之一)

python中的多态

就像我们看到的那样,times函数中表达式x*y的意义完全取决于x和y的对象类型,同样的函数,在一个实例下执行的是乘法,在另一个实例下执行的却是重复。Python把对某一对象在某种语法下的合理性交给那个对象自身来判断。也就是说, *作为一个分派机制,将执行的控制权移交给被处理的对象。
这种依赖类型的行为称为多态,其含义就是一个操作的意义取决于被操作对象的类型。因为python是动态类型语言,所以多态在python中随处可见。事实上,在python中所有都是多态的操作:print、index、*运算符,以及更多。
这是有意为之的,这算得上是这门语言简洁性和灵活性的一个表现。函数可以自动地应用到所有类别的对象上,只要对象支持所预期的接口(协议),函数就能处理它们。也就是说,如果传给函数的对象支持预期的方法和表达式运算符,那么它们对函数的逻辑来说就是有着即插即用的兼容性。
此外,如果传入的对象不支持这种预期的接口,那么python将会在*表达式运行时检测到错误,并自动抛出一个异常。因此编写代码错误检查通常是没有意义的。实际上,这样做反而会限制函数的功能,因为这会将函数限制在通过我们所编写的测试的那些类型。从宏观来说,python为对象接口编程,而不是数据类型。

重访多态

在这里插入图片描述
intersect函数也是多态的,它可以支持多种类型,只要其支持相应的对象接口。如上图,我们向函数传入了不同类型的对象(一个列表和一个元祖(混合类型)),并且仍然是选择出共有的元素,因为你没有必要去定义预先指明参数的类型,这个intersect函数很乐意对传给它的任何序列对象进行迭代,只要这些序列支持预期的接口就行。
对于intersect函数,这意味第一个参数必须支持for循环,并且第二个参数支持in成员测试。所有,满足这两点的对象都能够正常工作,与他们的具体类型无关——这包括了物理上存储的序列,例如字符串和列表。

“检查传入函数的对象类型”的做法有什么不妥?
检查传入函数的对象类型,实质上破坏了函数的灵活性,并把 函数限制在特定的类型上,没有这类检查时,函数可以处理更大范围的对象类型;任何支持函数所预期的接口的对象都将适用(接口一词是指函数所执行的一组方法和表达式运算符)

  • 作者:会飞的小司机odd
  • 原文链接:https://blog.csdn.net/qq_38469784/article/details/110853910
    更新时间:2023-01-10 15:08:29