第八章 函数-2
8.2 函数调用
定义一个函数只给了函数一个名称,指定了函数里包含的参数和函数体。函数定义完成以后,可以通过另一个函数调用执行,我们前面用的是main函数,也可以直接从程序里执行。下面看一个不用main函数的例子。比如要完成如下的一个分段函数,改造的网上找的一个函数,有点像水库大坝的样子(说到水库,想到今年夏天雨太大太多了,南方好多地方受灾,高考都受到了影响,今天2020年7月9日星期四安徽的一个县在使用高考备用卷进行考试,2020年是自然给人类的警示吗?):伤心了……


我们要做的是给出一个x值,计算出对应的y值。函数名为 fx,参数为x,返回值为y,函数体使用选择结构实现上述公式。自己试一下吧!
import math
def fx(x):
if 0<x<30:
y=math.cos(x)
elif 30<=x<50:
y=x
elif 50<=x:
y=math.sin(x)+30
else:
y=0
return y
x1=10
print(fx(x1))
x2=40
print(fx(x2))
x3=100
print(fx(x3))
这里没有使用main函数的方式,直接在程序里调用的fx函数。
绘制图形的代码如下,如果感兴趣请自学“第十章第三方库”。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0,100,1000)
interval0 = [1 if (i<30) else 0 for i in x]
interval1 = [1 if (i>=30 and i<50) else 0 for i in x]
interval2 = [1 if (i>=50) else 0 for i in x]
y = np.cos(x)* interval0 + x * interval1 + (np.sin(x)+30)*interval2
plt.plot(x,y)
plt.show()
下面的介绍的是函数里面的一些知识点,我们采用前面的一个函数例子介绍,求一个区间内所有整数的和,复制代码如下:
def n1n2Sum(n1,n2):
s=0
for i in range(n1,n2+1):
s=s+i
return s
def main():
x, y = eval(input("区间:"))
s=n1n2Sum(x,y)
print(2*s)
main()
8.2.1形参实参
函数定义时,括号里面的标识符是形式参数,简称形参。如def n1n2Sum(n1,n2),n1,n2是形参。函数调用时,括号里面的标识符是实际参数,简称实参。如s=n1n2Sum(x,y) 里面的x和y是实参。调用函数时,一般按照顺序从左到右依次进行参数值的传递,即x传递给n1,y传递给n2。
8.2.2位置参数和关键字参数
前面一小节的内容就是位置参数,即按照位置进行参数传递。Python还提供了关键字参数的传递方法,可以使用 key = value 语法发送参数,此时参数的顺序就没有关系了。如调用n1n2Sum函数可以采用s=n1n2Sum(x,y),也可以采用s=n1n2Sum(n1=x,n2=y),甚至使用s=n1n2Sum(n2=y, n1=x)这种指定参数名的方式,但是不建议使用顺序不是函数定义顺序的方式。
8.2.3默认参数
函数定义时,可以设置默认参数,当调用函数时如果不指定实参,则使用默认参数。函数可以混用默认值参数和非默认值参数。但是,非默认值参数必须定义在默认值参数之前。调用函数时,默认参数的值如果没有传入,则被认为是默认值。如函数定义写成下面形式
def n1n2Sum(n1=1,n2=10)
如果调用函数时不给出参数,s= n1n2Sum()则使用默认的n1=1,n2=10。但是必须遵守规则如下:
但是如果要给定默认参数,一个参数默认给定了的话,后面的所有参数也必须默认给定;或者如果后面的参数给定,所有前面的参数不给定。
8.2.4可变参数
可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。在参数前面加上*就是可变参数。在函数内部,参数numbers接收得到的是一个tuple,调用该函数时,可以传入任意个参数,包括0个参数,请看下面例子。
以数学题为例子,给定一组数字a,b,c……,计算a2 + b2 + c2 + ……
一般做法:
def calc(numbers):
sum=0
for n in numbers:
sum=sum+n*n
return sum
#在调用的时候,可以给出一个list或tuple
print(calc( [1,2,3] ))
print(calc( (1,2,3) ))
使用可变参数的方法:
def calc(*numbers): #定义了一个可变参数,在函数内部,参数numbers接收到的是一个tuple
sum=0
for n in numbers:
sum=sum+n*n
return sum
# 调用一个可变参数
numsl=[1,2,3,4,5,6]
print(calc( *numsl )) ## *numsl表示把numsl这个list的所有元素作为可变参数传进去
numst=(1,2,3,4,5,6)
print(calc( *numst )) ## *numst表示把numsl这个list的所有元素作为可变参数传进去
8.2.5返回值
不同于其它多数编程语言,Python可以设置返回值为多个,请看下面例子。
def f(x,y):
return x+y,x-y,x*y,x/y
t1,t2,t3,t4=f(9,5)
print(t1,t2,t3,t4)
此例子返回四个值:两个数的加减乘除四则运算值。
8.2.6不变对象可变对象
在 python 中,字符串string, 元祖tuple, 和 数值number 是不变对象,而 列表list,字典dict 等则是可变对象。不变对象,如数值类型变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。可变对象,如列表变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
不变对象可变对象主要是在函数调用的时候形参的改变是否影响实参的值,秘诀:不变对象不管形参怎么改变,实参的值都不变,因为它是不变对象;可变对象如果形参改变实参也同步改变。请看下面例子:
def nPrint(message, n):
while n > 0:
print(message)
n -= 1
k = 2
nPrint("A message", k)
print(k) #输出结果为2,因为k为不变对象

