ch08 函数和函数时编程
1、Python函数分类
(1)内置函数
(2)标准库函数
(3)第三方库函数
(4)用户自定义函数
在带星号的参数后面声明的参数强制为命名参数,如果这些参数没有默认值,且调用时必须使用命名参数赋值,则会引发错误
如果不需要带星号的参数,只需要强制命名参数,则可以简单地使用一个星号,如def total(initial=5, *, vegetables)
在声明函数时,通过带星的参数,如*param1,允许向函数传递可变数量的实参。调用函数时,从那一点后所有的参数被收集为一个==元组==
在声明函数时,也可以通过带双星的参数,如 **param2,允许向函数传递可变数量的实参。调用函数时,从那一值后所有的参数被收集为一个字典
带星或双星的参数必须位于形参列表的最后位置
Python中每个函数都具有返回值,如果没有return语句,则默认返回None
例题
def my_sum4(a, b, *c, **d): #各数字累加和
total = a + b
for n in c: #元组中各元素累加和
total = total + n
for key in d: #字典中各元素累加和
total = total + d[key]
return total
print(my_sum4(1, 2)) #计算1+2
print(my_sum4(1, 2, 3, 4, 5)) #计算1+2+3+4+5
print(my_sum4(1, 2, 3, 4, 5, male = 6, female = 7)) #计算1+2+3+4+5+6+7
**分析:**首先,a=1,b=2。
*c被收集成元组的形式,所以c=(3,4,5)
**d是以字典的形式收集,所以d={‘male’:6,’female’:7}
print(my_sum4(1,2,3,male=1,x=1,1,3,4))
注意不能够这样写,这样会报错,按照顺序
2、局部变量与全局变量
函数中定义的变量是指局部变量(或形式参数变量),而不是全局变量
在函数体中,可以引用全局变量,但如果函数内部的变量名是第一次出现且在赋值语句之前(变量赋值),则解释为定义局部变量
2.1、函数体错误引用全局变量的示例
m = 100
n = 200
def f():
print(m+5) #引用全局变量m
n += 10 #错误,n在赋值语句前面,解释为局部变量(不存在)
#测试代码
f()
控制台信息如下:
105
Traceback (most recent call last):
File "E:\Python\nterm\ch88\test1.py", line 11, in <module>
f()
File "E:\Python\nterm\ch88\test1.py", line 10, in f
n+=10
UnboundLocalError: local variable 'n' referenced before assignment
2.2、全局语句global示例
pi = 3.141592653589793 #全局变量
e = 2.718281828459045 #全局变量
def my_func():
global pi #全局变量,与前面的全局变量pi指向相同的对象
pi = 3.14 #改变了全局变量的值
print('global pi =', pi) #输出全局变量的值
e = 2.718 #局部变量,与前面的全局变量e指向不同的对象
print('local e =', e) #输出局部变量的值
#测试代码
print('module pi =', pi) #输出全局变量的值
print('module e =', e) #输出全局变量的值
my_func() #调用函数
print('module pi =', pi) #输出全局变量的值,该值在函数中已被更改
print('module e =', e) #输出全局变量的值
运行结果如下:
2.3、非局部语句nonlocal示例
def outer_func():
tax_rate = 0.17 #上级函数体中的局部变量
print('outer func tax rate =', tax_rate) #输出上级函数体中局部变量的值
def innner_func():
nonlocal tax_rate #不是所在块的局部变量,而是在上级函数体中定义的局部变量
tax_rate = 0.05 #上级函数体中的局部变量重新赋值
print('inner func tax rate =', tax_rate) #输出上级函数体中局部变量的值
innner_func() #调用函数
print('outer func tax rate =', tax_rate) #输出上级函数体中局部变量的值(已更改)
#测试代码
outer_func()
3、类成员变量
类成员变量是在类中声明的变量,包括静态变量和实例变量,其有效范围(作用域)为类定义体内
在外部,通过创建类的对象实例,然后通过“对象.实例变量”访问类的实例变量,或者通过“类.静态变量”访问类的静态变量
1、定义一个可以交换给定列表中两个指定下标的元素值的函数,随机混排给定列表的元素值
# 定义一个可以交换给定列表中两个指定下标的元素值的函数
import random
a= {1,2,3}
def exchange(a,i,j):
temp = a[i]
a[i] = a[j]
a[j] = temp
def shuffle(a):
n = len(a)#获取列表a的长度
for i in range(n):#0~n-1进行循环迭代
r = random.randrange(i,n)#取[1,n)之间的随记整数
exchange(a,i,r)#交换列表a中下标分别为i和r的元素值
4、内置函数的使用
4.1、eval()与exec()
通常,eval用于动态表达式求值,返回一个值;exec用于动态语句的执行,不返回值
print(exec("""if 2>1:print(True)"""))
# True
print(eval("""[ i for i in range(10) ]"""))
# eval()是动态表达式的求值
# ?动态语句的执行
a = eval("100.1")
print(a)
print(type(a))
print(type(eval("100")))
print(exec("print(11)"))
4.2、内置map()函数
通常,eval用于动态表达式求值,返回一个值;exec用于动态语句的执行,不返回值
map()函数示例1:自定义函数is_odd,应用该函数到可迭代对象的每一个元素,返回是否为奇数的可迭代对象结果
def is_odd(x):
return x%2==1
print(list(map(is_odd,range(5))))#[False, True, False, True, False]
print(list(map(abs,[1,-3,5,6,-2,4])))
#[1, 3, 5, 6, 2, 4]
def greater(x, y):
return x > y
print(list(map(greater, [1, 5, 7, 3, 9], [2, 8, 4, 6, 0])))
#[False, False, True, False, True]
5、函数的返回值
5.1、
编写函数,利用return语句返回函数值,求若干数中的最大值
求若干数中最大值的方法一般如下:
(1)将最大数的初值设为一个比较小的数,或者取第一个数为最大值的初值
(2)利用循环,将每个数与最大值比较,若此数大于最大值,则将此数设置为最大值
def my_max(a, b, *c): #求若干数中的最大值
max_value = a #假设第一个数为最大值
if max_value < b: #如果最大值小于b,则b为最大值
max_value = b
for n in c: #循环迭代c中每个元素n,如果最大值小于n,则n为最大值
if max_value < n:
max_value = n
return max_value #利用return语句返回最大值
# 测试用例
print(my_max(1,2))
print(my_max(1,2,3,5))
运行结果如下:
5.2、多条return语句
return语句可以放置在函数中任何位置,当执行到第一个return语句时,程序返回到调用程序
例题:判断素数(prime.py)。先编制一个判断一个数是否为素数的函数,然后编写测试代码,判断并输出1~99中的素数