**
继续修炼函数,理解函数的调用——《python学习手册》笔记之5
**
函数调用,在开始学那本笨办法书的时候,只知道用一个句号点,可以调用一个函数。但究竟何为调用,还是一头雾水。现在深入了一些,开始较全面的来接触函数了。上一篇笔记谈到函数的结构,那个函数调用的雾水老是漂浮在我心头,活生生的一个困惑。这篇笔记,就用来弄明白一点函数的调用的,先从调用的字符意义开始理解起。
标题一、简单调用:何谓函数的调用
函数在python中最重要的一点是,它在一处编写好,这个编好的函数可以在多处运行。它以打包的形式不止一处,也不止一次地可以反复使用。这么强大的反复使用功能,自然就有个如何调用函数的问题。这个调用,英文应该是call。Calling function,这被翻译为调用函数。
调用当然有个调用主体,这被称为调用者,好像不是指编代码的那个人,而是要使用某个函数的某个编码对象。由这个编码对象来使用某个函数,这样一个让某个函数服务于某个对象的编码行为,大概就是调用的基本意义。
先用几个简单的函数实例来说明这个调用。
函数调用实例1`
>>> def plus(x, y): 这一行用plus创建和指派了函数,包括参数
... return x + y 这一行是函数体,它在那里等待调用
... 这一行用enter键运行了函数plus,大概封装了这个函数
>>> plus(3,8) 这一行就是调用函数plus,给参数赋值,这个函数运行
11 运行结果
这是一个简单的算术函数,函数的基本结构全有。一个def的标识所带的函数名,参数和冒号在表明一个函数已经创建出来,但这个函数还没有执行。这个加plus想说明是参数加法的使用,但实际上加只是一个函数名称,括号内的两个参数,它们究竟用什么运算,那看你运用时的需要,调用为乘法也是可以的。
函数调用实例2
>>> def plus(x, y):
... return x * y
...
>>> plus(4,7) 调用函数plus,给参数赋值
28
所以,这个加法名称只是提到你最初使用的是加运算,而后你用这个函数还可以做加法之外的许多操作。因此这样一个函数,起名为func这样一个泛称的名字可能更适合。它除了算术运算,还可以做字符的重复呢。
函数调用实例3
>>> def func(x, y):
... return x * y
...
>>> func(4, 7) 调用函数func,给参数赋值
28
>>> func('name', 7) 调用函数func,给参数赋值
'namenamenamenamenamenamename'
>>> func(4, 'joe') 调用函数func,给参数赋值
'joejoejoejoe'
>>> func(2, 'two') 调用函数func,给参数赋值
'twotwo'
显然python函数的调用,可以是一个运算的重复,也可以是扩展运算的重复。这当然是最简单的函数调用。
标题二、调用一个函数之前,必须先有这个函数,或者是创建的,或者是现成的
刚才的例子已经说明了这一点,但那个函数似乎太简单,只有return一行的函数体来体现这个函数。这里给一个稍微复杂一点的例子,我们创建一个使用for循环的函数实例,然后再把这个for函数作为待调用的函数封装起来。
标题(一)准备一个for函数,显然以下函数体比上述函数体复杂了不少,函数体有五行。
>>> def union(sect1, sect2, sect3):
... res = []
... for x in sect1:
... if x in sect2 and sect3:
... res.append(x)
... return res
这里的res.append(x)也可以看作是名称res用点调用了append这个函数,这以前就听说过,在这里再来一次温习。这表明后面呈现的结果既用到了创建的for函数,也用到了python中已经留存的现成常规函数append。
标题(二)用点来调用append函数,给参数赋值调用for函数,这个for中又包括着集合交集运算的现成函数intersect
给三个参数赋值,使用那个做好的for函数名称,如前述简单函数调用方式几乎相同。三个参数赋值的共有元素就在结果中出现,这正是以上for函数的功能。它定义了一个空集合res,然后遍历三个字符串,从中获取共有的字符。这些字符依照append功能相继加在那个[]列表中。
>>> S1 = 'funny'
>>> S2 = 'unhappy'
>>> S3 = 'punnyes'
>>> union(S1, S2, S3) 调用函数union,用赋值后的参数名
['u', 'n', 'n', 'y']
奇怪的是,这个类似于集合交集的运算所形成的列表,元素是可以重复的。我的印象,集合中的交不允许重复元素出现,只能出现一次。从这个for函数中还可以知道,在这个循环的创建中,也已经包含了一个内置的交际函数运算intersect。就此而言,这个函数中还调用了另一个内置的交集运算。由此,这个调用的方式就可以更为简洁,一个单行的列表就可搞掂。
>>> [x for x in S1 if x in S2 and S3]
['u', 'n', 'n', 'y']
标题(三)嵌套函数的调用,一种更为普遍的调用模式,嵌套函数记住了套住它的那个函数参数值,如果它的参数还没有赋值的话
函数之中套函数,这是python代码中的常事,上述for函数就是实例。假若我们在一个函数f1中又嵌套另一个函数f2,那么我们调用f2时,结果如何呢?
先有一个函数在:
>>> def func1():
... X = 144
... def func2():
... print(X)
... return func2
...
然后我们调用函数f1,但f1运行时运行的是其嵌套的func2,于是结果依然是func1中X的赋值。这个调用也有点奇怪,似乎单独的func2,如果其参数没有赋值,就默认出现func1的赋值似的。
>>> behavir = func1()
>>> behavir()
144
标题三、直接函数调用和间接函数调用
在简单函数调用部分,已经感觉到函数名称是柔性特强的字符,并没有什么特别的含义,唯一独特的含义就是它表示一个函数名。现在跑到第十九章了,似乎印证了我的函数名称感觉。而那个间接函数调用的描述部分,正是触动我专写一篇调用笔记的地方。有间接函数调用,自然就应该有直接函数调用,先对这一对概念做点启蒙。
何谓直接函数调用?当一个函数名作为一个对象,自由地把这个对象赋给其它的名称来予以调用的时候,这大概就是所谓的直接函数调用。
函数直接调用实例
>>> def xinxi(information):
... print(information)
...
>>> xinxi('information') 直接通过原初的函数名调用该函数的参数
information
前述的一些简单函数调用,大抵都是这种直接调用的例子。
但是,如果我们在调用函数时,先给函数名一个变元简称,把函数名当作是对于变元的赋值,然后在该函数的参数中填以任意其它字符,则这种函数调用方式,就是函数的间接调用,函数的名称变了,函数的参数也变了,但那个函数架构还在,例如,承接以上刚刚创建的函数def xinxi(information),我们可以这样做一个简单的间接函数调用实例:
>>> x = xinxi
>>> x('flow strenm')
flow strenm
这涉及到函数相关的诸多议题,对象啊,数据结构啊,属性啊等等还只是有粗略理解的观念,不敢展开来谈。且仿教材间接函数调用案例制作一个实例,作为本篇的终结。
一个间接函数调用的例子
>>> def produce(logging):
... def xinxi(information):
... print(logging + ':' + information)
... return xinxi
...
>>> M = produce('Zhou')
>>> M('Wine')
Zhou:Wine
>>> M('Tea!')
Zhou:Tea!
这样的调用,给人直观感觉就是python函数太灵活柔性了,变化形式千奇百怪,但函数的核心东西却似乎还在。不过,这里提到的函数核心,我还真不知道该如何描述。我只觉得对于函数的结构,函数的调用有了点启蒙。它的属性,它作为对象的和python的其它对象有什么区分,它的形形色色,还是在朦胧雾水之中,有待进一步提升。