python—第11天—函数
函数
世界级的编程大师Martin Fowler先生曾经说过:“代码有很多种坏味道,重复是最坏的一种!”。
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也
可以自己创建函数,这被叫做用户自定义函数。
定义一个函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号**()**。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
函数调用
定义一个函数只给了函数一个名称,指定了函数里包含的参数,和代码块结构。
这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从Python提示符执行。
return 语句
return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。
全局变量和局部变量
全局变量(没有写在任何函数里面的变量)
举报变量(定义在函数内部的变量)
Python程序中搜索一个变量是按照LEGB顺序进行搜索
Local(局部作用域) —> Embeded(嵌套作用域) —> Global(全局作用域)----> Built-in(内置作用域) —> NameError: name … not defined
global —> 声明使用全局变量或者定义一个局部变量将其放到全局作用域
nonlocal —> 声明使用嵌套作用域的变量(不使用局部变量)
x = 100
def foo():
x = 200
def bar():
x = 300
print(x)
bar()
print(x)
foo()
print(x)
结果:
300 200 100
x = 100
def foo():
global x
x = 200
def bar():
x = 300
print(x)
bar()
print(x)
foo()
print(x)
结果:
300 200 200
x = 100
def foo():
x = 200
def bar():
nonlocal x
x = 300
print(x)
bar()
print(x)
foo()
print(x)
结果:
300 300 200
定义和使用函数
计算组合数:C(M, N) = M! / N! / (M - N)! (M >= N)
将来我们使用函数的时候,要么是Python标准库中或三方库中的函数(别人写好可以直接用的),要么是自定义的函数(需要自己编写,将来可以由自己或他人重复使用)
def fac(num):
"""求阶乘"""
result = 1
for i in range(2, num + 1):
result *= i
return result
m = int(input('m = '))
n = int(input('n = '))
print(fac(m)//fac(n)//fac(m - n))
练习1:
写一个实现生成指定长度的随机验证码(有数字和英文字母构成)的函数。
写好了之后,通过调用该函数,生成10组随机验证码。
import string
import random
def captcha(length=4):
"""
随机生成验证码
:param length: 验证码的长度
:return: 随机验证码
"""
selected_chars = random.choices(string.ascii_letters + string.digits, k=length)
return ''.join(selected_chars)
for _ in range(10):
print(captcha(6))
string.ascii_letters
包含所有大小写的字母
string.digits
包含0-9的数字
练习2:
写一个函数判断一个正整数是不是质数。(自变量:正整数,因变量:True / False)写好之后,
通过这个调用这个函数,输出2-100范围内的质数。
import math
def prime(num):
"""
判断一个正整数是不是质数
:param num: 正整数的值
:return: 如果是质数返回True,否则返回False
"""
for i in range(2, int(math.sqrt(num) + 1)):
if num % i == 0:
return False
return num != 1 and True
for x in range(2, 100):
if prime(x):
print(x, end=' ')
练习3:
用函数实现求两个数的最大公约数和最小公倍数。
def gcd(x, y):
"""求最大公约数"""
while y % x != 0:
x, y = y % x, x
return x
def lcm(x, y):
"""求最小公倍数"""
return x * y // gcd(x, y)
m = int(input('m = '))
n = int(input('n = '))
print(f'最大公约数为:{gcd(m, n)}, 最小公倍数为:{lcm(m, n)}')
练习4:
设计一个函数,传入一个列表(列表中是一组样本数据),计算样本数据的极差(最大值和最小值
的差)。
def ptp(nums):
"""求极差"""
return max(nums) - min(nums)
list1 = [90, 50, 95, 42, 32, 15]
print(ptp(list1))
练习5:
传入一个列表(列表中是一组样本数据),设计计算方差和标准差的函数。
def average(data):
"""求均值"""
return sum(data) / len(data)
def var(nums):
"""求方差"""
x_bar = average(nums)
temp = [(num - x_bar) ** 2 for num in nums]
return sum(temp) / (len(temp) - 1)
def std(data):
"""求标准差"""
return var(data) ** 0.5
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(f'方差为: {var(list1)},标准差为: {std(list1)}')
练习6:
设计一个函数,传入一个列表(列表中是一组样本数据),找出样本数据的中位数。
def median(data):
"""求中位数"""
temp = sorted(data)
a = len(temp)
if a % 2 == 0:
return (temp[a // 2] + temp[a // 2 - 1]) / 2
else:
return temp[a // 2]
list1 = [1, 5, 9, 2, 6, 4, 8, 7, 3, 10]
print(f'中位数为: {median(list1)}')
写程序的终极原则:
高类聚,低耦合 —> high cohesion low coupling
设计函数最为重要的原则:单一职责原则(一个函数只做一件事情) —> 高度内聚