python 之用户自定义函数
什么是函数?
函数无非就是将代码块进行封装,想用的时候拿来用,减少代码量,提高效率。
函数的定义
定义一个函数需要:
1.def关键字,def 后面空一格输入函数名称,函数命名时尽量简短,且具有意义,能通过函数名窥见该函数实所实现的功能,函数名称后面紧跟着一对英文圆括号()和英文冒号:
即 def关键字、函数名、括号、冒号缺一不可
2.括号里面存放参数,根据需要可传可不传
3.一般使用三重引号注释函数所实现功能,并放于第一行(根据编码者习惯可写可不写)
4.冒号以下都是函数内容
5.return 可写可不写,根据实际情况,若不填写时,该函数无返回值
def my_fun(parameters): """ 实现XXXXX功能 :return: """ Function body return expression
定义一个简单的函数
def marks(): """ 分数校验 :return: """ mark = float(input("请输入分数:")) if mark < 60: return False else: return True
函数定义后不会执行,需要调用才会去执行

函数的调用
def sub(a, b): """ 实现减法 :param a: :param b: :return: """ return a - b result = sub(2, 5) print(result)
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py -3
或者由其他函数调用执行
import random import string import hashlib def random_str(number): """ 生成随机码 :param number: :return: """ code = ''.join(random.sample(string.digits + string.ascii_letters, int(number))) return code def md5_str(number): """ md5加密 :param number: :return: """ md5_data = hashlib.md5() md5_data.update(random_str(number).encode()) # 调用random_str()函数生成随机数 sign = md5_data.hexdigest() return sign if __name__ == '__main__': string = md5_str(8) print(string)
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 345b36fc3ee89f786bc122cb3f8c26f2
参数使用
上面的例子中已用到了参数,在python实际使用中,参数分为形参、实参
形参:定义函数时传递的参数
实参:调用函数时传递的参数
def len_str(data): # 形参 data """ 获取字符串长度 :param data: :return: """ count = 0 for i in data: count += 1 return count print(len_str("If you plant a melon, you get a melon")) # 传入实参
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 37
位置参数(必备参数)
调用时传入的参数必须与声明中的参数一一对应,包括位置、数量、参数类型
def max_data(da): """ 获取列表中最大值 :param da: :return: """ for i in range(len(da) - 1): for j in range(len(da)-1 - i): if da[j] > da[i]: temp = da[j] da[j] = da[j+1] da[j+1] = temp return da[len(da) - 1] print(max_data())
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py Traceback (most recent call last): File "D:/demo/funtion_1.py", line 63, in <module> print(max_data()) TypeError: max_data() missing 1 required positional argument: 'da'
def student(name, age): stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20} for key, value in stu.items(): if name == key and age == value: return "该考生存在" print(student(19, "王二")) # name 对应19, age 对应王二
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 查无此人
def student(name, age): stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20} for key, value in stu.items(): if name == key and age == value: return "该考生存在" print(student("王二", 19)) # name 对应王二, age 对应19
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 该考生存在
关键字参数
关键字参数是指在调用时,使用形参名+传入的参数值(parameter1=value1,parameter2=value2),使用关键字参数时不需要与声明中的位置对应
def student(name, age): stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20} for key, value in stu.items(): if name == key and age == value: return "该考生存在" print(student(age=19, name="王二")) # name、age 位置可不对应
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 该考生存在
位置参数与关键字参数混合使用
混合使用时,位置参数一定要在关键字参数前,不然程序报错,不可执行
def student(name, age): stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20} for key, value in stu.items(): if name == key and age == value: return "该考生存在" print(student(age=19, "王二")) # 当关键字参数在位置参数前时抛出"位置参数必须在关键字参数前"
File "D:/demo/funtion_1.py", line 73 print(student(age=19, "王二")) # 当关键字参数在位置参数前时抛出"位置参数必须在关键字参数前" ^ SyntaxError: positional argument follows keyword argument
def student(name, age): stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20} for key, value in stu.items(): if name == key and age == value: return "该考生存在" print(student("王二", age=19,))
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 该考生存在
关键字参数与位置参数混合使用,容易出现一个坑,TypeError: xxxxx() got multiple values for argument xxxxx'
def student(name, age): stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20} for key, value in stu.items(): if name == key and age == value: return "该考生存在" print(student(19, name="王二"))
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py Traceback (most recent call last): File "D:/demo/funtion_1.py", line 73, in <module> print(student(19, name="王二")) TypeError: student() got multiple values for argument 'name'
默认参数
默认参数是指在定义时传入参数值,调用时未传入参数则使用默认传入的参数值,否则使用调用传入的参数值
def marks(mark=60): mar = float(input("请输入你的分数")) if mar > mark: return "及格线为: %s, 你及格了" % mark else: return "及格线为: %s, 你需要补考" % mark print(marks(85)) # 传入参数,此时使用调用时传入的参数值
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 请输入你的分数80 及格线为: 85, 你需要补考
def marks(mark=60): mar = float(input("请输入你的分数")) if mar > mark: return "及格线为: %s, 你及格了" % mark else: return "及格线为: %s, 你需要补考" % mark print(marks()) # 不传入参数,此时使用定义时传入的参数值
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 请输入你的分数80 及格线为: 60, 你及格了
动态参数
动态参数又称为不定长参数,在使用时,根据需要可以传入任意个参数,动态参数有两种形式,*args, **kwargs,参数间的位置排序为:位置参数、默认参数、*args动态参数、**kwargs动态参数、关键字参数
*args: 表示接受任意多个实际参数将其放到一个元组中,如果参数是个列表,会将整个列表当做一个参数传入
def marks(*args): print(args) for i in args: print(i) (marks(["张三", "李四", "王二", "麻子"], [50, 50, 70, 90]))
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py (['张三', '李四', '王二', '麻子'], [50, 50, 70, 90]) ['张三', '李四', '王二', '麻子'] [50, 50, 70, 90]
以上是将列表当成一个参数,若要分解成多个参数,调用时可以在参数前加 *,也称为解包(适用于任何序列类型数据对象)
def marks(*args): print(args) for i in args: print(i) (marks(*["张三", "李四", "王二", "麻子"], *[50, 50, 70, 90]))
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py ('张三', '李四', '王二', '麻子', 50, 50, 70, 90) 张三 李四 王二 麻子 50 50 70 90
def marks(*args): print(args) for i in args: print(i) (marks(*{"张三": 95, "李四": 20, "王二": 88, "麻子": 91})) # 将字典中的key作为参数
('张三', '李四', '王二', '麻子') 张三 李四 王二 麻子
**kwargs:表示接受任意多个实际参数将其放到一个字典中,类似关键字参数
def marks(**kwargs): print(kwargs) for name, mark in kwargs.items(): print(name, ":", mark) (marks(张三=90, 李四=20)) # 通过关键字传入
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py {'张三': 90, '李四': 20} 张三 : 90 李四 : 20
def marks(**kwargs): print(kwargs) for name, mark in kwargs.items(): print(name, ":", mark) (marks(**{"张三": 95, "李四": 20, "王二": 88, "麻子": 91})) # 通过字典传入,在参数前加入**,函数会把dict中所有键值对转换为关键字参数传进去
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py {'张三': 95, '李四': 20, '王二': 88, '麻子': 91} 张三 : 95 李四 : 20 王二 : 88 麻子 : 91
*args, **kwagrs混合使用
def persons(name, age, *args, **kwargs): print(args) print(kwargs) infos = '' if "王" in name or age < 20: if kwargs['address'] == "深圳": for info in args: infos += info for k, v in kwargs.items(): print(name, "基础资料有", k, ":", v) print(name, "年龄在20的深圳小青年,其他信息有", infos) persons("王二", 19, "文艺", "摇滚", address="深圳", job="student")
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py ('文艺', '摇滚') {'address': '深圳', 'job': 'student'} 王二 基础资料有 address : 深圳 王二 基础资料有 job : student 王二 年龄在20的深圳小青年,其他信息有 文艺摇滚
函数变量作用域
根据变量的定义位置,决定变量的作用范围
局部变量:定义在函数内部的变量,只在函数内部有效,执行完后,局部变量会被释放,无法再次访问
全局变量:定义在整个文件层次上,可以在整个程序范围内访问
def sum(a, b): count = a + b return count # count 局部变量 print(sum(1, 4))
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 5
guess = -10 # 全局变量 def compare(): times = 3 while times > 0: value = float(input("请输入你所猜数字, 你还有%s次机会" % times)) if value == guess: return "恭喜,猜对啦" else: times -= 1 return "很遗憾,你的次数用完啦" print(compare())
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 请输入你所猜数字, 你还有3次机会3 请输入你所猜数字, 你还有2次机会0 请输入你所猜数字, 你还有1次机会9 很遗憾,你的次数用完啦
尝试在函数内修改全局变量
guess = -10 # 全局变量 def compare(): times = 3 while times > 0: value = float(input("请输入你所猜数字, 你还有%s次机会" % times)) if value == guess: return "恭喜,猜对啦" else: guess = 1 times -= 1 return "很遗憾,你的次数用完啦" print(compare())
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 请输入你所猜数字, 你还有3次机会24 Traceback (most recent call last): File "D:/demo/funtion_1.py", line 135, in <module> print(compare()) File "D:/demo/funtion_1.py", line 127, in compare if value == guess: UnboundLocalError: local variable 'guess' referenced before assignment
在函数内部修改全局变量报错了,这是因为,Python 的解释器会默认函数内部的变量为局部变量,然而局部变量 guess 又没有声明,因此就无法执行相关操作。那么如果要在函数内更改全局变量呢?
这里可以引入 global
def compare(): global guess print("修改前的谜底:%s" % guess) times = 3 while times > 0: value = float(input("请输入你所猜数字, 你还有%s次机会" % times)) if value == guess: return "恭喜,猜对啦" else: guess = 1 times -= 1 return "很遗憾,你的次数用完啦", "此时谜底为:%s" % guess print(compare())
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 修改前的谜底:-10 请输入你所猜数字, 你还有3次机会64 请输入你所猜数字, 你还有2次机会978 请输入你所猜数字, 你还有1次机会3 ('很遗憾,你的次数用完啦', '此时谜底为:1')
函数嵌套
函数嵌套是指函数里面又存在函数,经典案例递归
def factorial_calculation(): number = int(input("请输入整数")) if number <= 0: return "请输入大于0的正整数" def factorial(number): if number <= 1: return 1 return number * factorial(number-1) return factorial(number) print(factorial_calculation())
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py 请输入整数6 720
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~