函数概述

从实现函数的角度来看,其至少需要想清楚以下 3 点:
• 函数需要几个关键的需要动态变化的数据,这些数据应该被定义成函数的参数。
• 函数需要传出几个重要的数据(就是调用该函数的人希望得到的数据),这些数据
应该被定义成返回值。
• 函数的内部实现过程。

函数创建和调用

#1). 定义函数:
#def 函数名(参数1, 参数2........):
#函数执行的内容
#2). 定义函数时指定参数和返回值的类型
#def mymax(num1: int, num2: int) -> int:
#代表num1需要传入整形, num2需要传入整形, 返回值必须是整形。
#3). 函数的帮助文档: 三引号

def mymax(num1: int, num2: int) -> int: """ 求两数的最大值 :param num1: 第一个数值 :param num2: 第二个数值 :return: 最大值 """ #if num1 > num2: #return num1 #else: #return num2 return num1 if num1 > num2 else num2#调用函数max_num = mymax(2, 1)print(max_num)#print(help(mymax))定义空函数

#定义函数的时候, 函数内部代码不会执行。 只有在调用函数的时候, 才会执行代码的内容.

def login(username: str, passwd: str) -> bool: """ 实现用户登录 :param username: 用户名 :param passwd: 密码 :return: 是否登录成功 """ passlogin('root', 'westos')

返回值理解:
#定义函数的时候, 函数内部代码不会执行。 只有在调用函数的时候, 才会执行代码的内容.

def login(username: str, passwd: str) -> bool: """ 实现用户登录 :param username: 用户名 :param passwd: 密码 :return: 是否登录成功 """ if username == 'root' and passwd == 'westos': print('login ok') return True else: print('login fail') return False

#没有返回值,默认返回None

result = login('root', 'westos')print(result)

函数里面可以调用其他函数:

def printOneLine(): """打印一行提示""" print('*'*30)

def printNumLine(num: int): # num=3 """打印多行提示""" for count in range(num): printOneLine()printNumLine(3)局部变量:

• 局部变量,就是在函数内部定义的变量
• 不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响
• 局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用
#局部变量,就是在函数内部定义的变量, 只在函数内部生效
def save_money(money):
"""存钱"""
#函数内部定义的变量
#如何将局部变量声明为全局变量? global 变量名, 这样操作, 外部就可以访问到该局部变量.
global allMoney
allMoney = 100
print(id(allMoney))
print("存钱前: ", allMoney)
allMoney += money
print("存钱后: ", allMoney)

def view_money():

函数内部定义的变量

allMoney = 500print(id(allMoney))print(allMoney)

if name == 'main':
save_money(150)
print(allMoney)

全局变量

#没有在函数内部定义的函数, 我们就称为全局变量。
如果一个变量,既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是全局变量。
• 在函数外边定义的变量叫做全局变量
• 全局变量能够在所有的函数中进行访问
• 如果在函数中修改全局变量,那么就需要使用global进行声明,否则出错
• 如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的
allMoney = 100

#局部变量,就是在函数内部定义的变量, 只在函数内部生效
def save_money(money):
"""存钱"""
#函数内部定义的变量
#如何将局部变量声明为全局变量? global 变量名, 这样操作, 外部就可以访问到该局部变量.

global allMoney allMoney = 200 print("存钱前: ", allMoney) allMoney += money print("存钱后: ", allMoney)if __name__ == '__main__': save_money(100)

不使用global声明全局变量时不能修改全局变量?global的本质是声明可以修改全局变量的指向, 即变量可以指向新的数据。

1). 不可变类型的全局变量: 指向的数据不能修改, 不使用global时无法修改全局变量。
2). 可变类型的全局变量: 指向的数据可以修改, 不使用global时可以修改全局变量。

可变数据类型与不可变数据类型在全局变量修改的不同

import pprint#定义了两个全局变量allMoney = 100operator = []def save_money(money): testCount = 1000 global allMoney print("存钱之前: ", allMoney, operator) allMoney += money operator.append("存钱%s元" %(money)) print("存钱之后: ", allMoney, operator) #locals(): 当前局部范围内所有变量组成的“变量字典”。 print(locals())if __name__ == '__main__': save_money(10) #save_money(20) #save_money(30) ##globals():全局范围内所有变量组成的“变量字典”。 #pprint.pprint(globals().keys())默认参数

#def mypow(x, y=2, z=None):#"""求次方, 默认求2次方"""#return x**y#if __name__ == '__main__':#print(mypow(2)) # 4 x=2, y=2,z=None#print(mypow(2, 3)) # 8 x=2, y=3,z=None#默认参数可以降低调用函数的难度。def connect_mysql(user, passwd, host='localhost', port=3306, charset='utf8'): print('connect mysql......', user, passwd, host, port, charset)if __name__ == '__main__': connect_mysql(user='root', passwd='redhat') connect_mysql(user='root', passwd='redhat', host='172.25.254.197')可变参数

#形参(必选参数, 默认参数, 可变参数/位置参数,)
#args是形参, 可以任意修改名称.
#
args是可变参数,可以传入1个、2个、3个......个参数。将所有的参数封装成元组, 赋值给变量args.

def square_sum(*args): # args=(1, 2, 3, 4) """ 求多个数值的平方和 args = (1, 2, 3, 4) count arg result 1 1 1 2 2 1+4=5 3 3 5+9=14 4 4 14+16=30 :return: """ result = 0 for arg in args: result = result + arg ** 2 return result#1). 调用函数#square_sum(1)#square_sum(1, 2)print(square_sum(1, 2, 3))print(square_sum(1, 2, 3, 4))关键字参数

import random
print()

#关键字参数允许传入 0 个或任意个含参数名的参数;
#kwargs是形参, 可以任意修改名称, 一般是kwargs
#kwargs是以字典的数据类型存储用户传入的信息
def record_student_info(name, age, **info):
print(name, age, info)

#1). 调用参数
record_student_info('root', 10)
record_student_info('root', 10, hobby='python program', city='西安', english_level='CET-6')

#2). 解包
info = dict(hobby='python program', city='西安', english_level='CET-6')
record_student_info('westos', 10, **info)

匿名函数

匿名函数指一类无须定义标识符的函数或子程序。Python用lambda语法定义匿名函数,
只需用表达式而无需申明。(省略了用def声明函数的标准步骤)
lambda函数的语法只包含一个语句,如下:

mymax = lambda num1, num2 : num1 if num1 > num2 else num2print(mymax(1, 2))mypow = lambda x, y=2 : x**yprint(mypow(2))print(mypow(2, 3))

lambda函数能接收任何数量的参数但只能返回一个表达式的值
匿名函数当作参数传入:
#应用场合1: 函数作为参数传递

def fun(num1, num2, operator_fun=pow): return operator_fun(num1, num2)print(fun(2, 3))print(fun(2, 3, lambda x, y: x+y))

匿名函数作为参数传递:

from prettytable import PrettyTabledef show(goods): """友好的以表格的方式打印商品信息""" table = PrettyTable(field_names=['Name', 'Count', 'Price']) for good in goods: table.add_row(good) print(table)goods = [ ("Python核心编程", 200, 378.9), ("Java核心编程", 300, 278.9), ("Php核心编程", 100, 78.9), ("Ruby核心编程", 260, 178.9),]print("按照数量进行排序".center(30, '*'))goods.sort(key=lambda x:x[1])show(goods)print("按照价格进行排序".center(30, '*'))goods.sort(key=lambda x:x[2])show(goods)

(2018-携程-春招题)
给定一个整形数组, 将数组中所有的0移动到末尾, 非0项保持不变;
在原始数组上进行移动操作, 勿创建新的数组;
• 输入: 数组的记录;0 7 0 2
• 输出: 调整后数组的内容; 7 2 0 0

li = [0, 7, 0, 2]"""0 7 0 2\ \ \ \1 0 1 0由小到大:0 0 1 1\ \ \ \7 2 0 0"""li.sort(key=lamb```da x: 1 if x == 0 else 0)print(li)# 递归函数一个函数在内部调用自己本身,这个函数就是递归函数需求:计算阶乘 factorial: n! = 1 * 2 * 3 * ... * ndef factorial(num): """通过递归的方式求num的阶乘""" #递归退出的条件: num <= 1 #阶乘循环的内容: num! = num * (num-1)! if num > 1: result = num * factorial(num-1) else: result = 1 return resultif __name__ == '__main__': print("2的阶乘: ", factorial(2)) print("3的阶乘: ", factorial(3)) print("4的阶乘: ", factorial(4))递归实现Fib

from functools import lru_cache@lru_cache(maxsize=1000)
br/>@lru_cache(maxsize=1000)
#1. 递归退出的条件: num=1 or num=2 直接退出递归. F(1)=1,F(2)=1
#2. 递归的规则:F(n)=F(n-1)+F(n-2)
if num == 1 or num == 2:
return 1
else:
return fib(num - 1) + fib(num - 2)

if name == 'main':
print("第5个Fib数列:", fib(5)) # 5
print("第8个Fib数列:", fib(8)) # 21
print("第100个Fib数列:", fib(100))

递归实现汉诺塔:movecount = 0def hanoi(n=3, start='A', cache='B', target='C'): """ :param n: 盘子个数 :param start: 初始塔 :param cache: 缓冲塔 :param target: 目标塔 :return: None """ #递归函数规则: #1). 什么情况下退出递归? 当盘子格式n=1是退出递归; #2). 递归的规则: #- hanoi(n-1, start, target ,cache) #- hanoi(1, start, cache ,target) #- hanoi(n-1, cache, start,target) if n == 1: print("盘子从%s移动到%s" %(start, target)) global movecount movecount += 1 else: hanoi(n - 1, start, target, cache) hanoi(1, start, cache, target) hanoi(n - 1, cache, start, target)hanoi(4)print(movecount)这周作业

判断闰年:

num=int(input("输入:"))def nian(year): return (year %4 ==0 and year % 100 !=0) or (year %400 ==0)print(nian(num))99乘法表:

def printLine(row): for col in range(1,row+1): print("{}*{}={}\t".format(col,row,col*row),end=" ") print("")for row in range(1,10):printLine(row)

求素数:素数的特征是除了1和其本身能被整除,其它数都不能被整除的数'def num(a,b): for i in range(a,b): f = 0 for j in range(2,i -1): if i % j ==0: f = 1 break if f == 0: print(i)num(100,200)

# 编写“学生管理系统”,要求如下:# • 必须使用自定义函数,完成对程序的模块化# • 学生信息至少包含:姓名、年龄、学号,除此以外可以适当添加# # • 必须完成的功能:添加、删除、修改、查询、退出 import re # 导入正则表达式模块 import os # 导入操作系统模块 filename = "students.txt" # 定义保存学生信息的文件名 def menu(): # 输出菜单 print(''' 学生信息管理系统 =============== 功能菜单 =============== │ 1 录入学生信息 │ │ 2 查找学生信息 │ │ 3 删除学生信息 │ │ 4 修改学生信息 │ │ 5 排序 │ │ 6 统计学生总人数 │ │ 7 显示所有学生信息 │ │ 0 退出系统 ''') def main(): ctrl = True # 标记是否退出系统 while (ctrl): menu() # 显示菜单 option = input("请选择:") # 选择菜单项 option_str = re.sub("\D", "", option) # 提取数字 if option_str in ['0', '1', '2', '3', '4', '5', '6', '7']: option_int = int(option_str) if option_int == 0: # 退出系统 print('您已退出学生成绩管理系统!') ctrl = False elif option_int == 1: # 录入学生成绩信息 insert() elif option_int == 2: # 查找学生成绩信息 search() elif option_int == 3: # 删除学生成绩信息 delete() elif option_int == 4: # 修改学生成绩信息 modify() elif option_int == 5: # 排序 sort() elif option_int == 6: # 统计学生总数 total() elif option_int == 7: # 显示所有学生信息 show() '''1 录入学生信息''' def insert(): stdentList = [] # 保存学生信息的列表 mark = True # 是否继续添加 while mark: id = input("请输入ID(如 1001):") if not id: # ID为空,跳出循环 break name = input("请输入名字:") if not name: # 名字为空,跳出循环 break try: english = int(input("请输入英语成绩:")) python = int(input("请输入Python成绩:")) c = int(input("请输入C语言成绩:")) except: print("输入无效,不是整型数值....重新录入信息") continue stdent = {"id": id, "name": name, "english": english, "python": python, "c": c} # 将输入的学生信息保存到字典 stdentList.append(stdent) # 将学生字典添加到列表中 inputMark = input("是否继续添加?(y/n):") if inputMark == "y": # 继续添加 mark = True else: # 不继续添加 mark = False save(stdentList) # 将学生信息保存到文件 print("学生信息录入完毕!!!") # 将学生信息保存到文件 def save(student): try: students_txt = open(filename, "a") # 以追加模式打开 except Exception as e: students_txt = open(filename, "w") # 文件不存在,创建文件并打开 for info in student: students_txt.write(str(info) + "\n") # 按行存储,添加换行符 students_txt.close() # 关闭文件 '''2 查找学生成绩信息''' def search(): mark = True student_query = [] # 保存查询结果的学生列表 while mark: id = "" name = "" if os.path.exists(filename): # 判断文件是否存在 mode = input("按ID查输入1;按姓名查输入2:") if mode == "1": id = input("请输入学生ID:") elif mode == "2": name = input("请输入学生姓名:") else: print("您的输入有误,请重新输入!") search() # 重新查询 with open(filename, 'r') as file: # 打开文件 student = file.readlines() # 读取全部内容 for list in student: d = dict(eval(list)) # 字符串转字典 if id is not "": # 判断是否按ID查 if d['id'] == id: student_query.append(d) # 将找到的学生信息保存到列表中 elif name is not "": # 判断是否按姓名查 if d['name'] == name: student_query.append(d) # 将找到的学生信息保存到列表中 show_student(student_query) # 显示查询结果 student_query.clear() # 清空列表 inputMark = input("是否继续查询?(y/n):") if inputMark == "y": mark = True else: mark = False else: print("暂未保存数据信息...") return '''3 删除学生成绩信息''' def delete(): mark = True # 标记是否循环 while mark: studentId = input("请输入要删除的学生ID:") if studentId is not "": # 判断要删除的学生是否存在 if os.path.exists(filename): # 判断文件是否存在 with open(filename, 'r') as rfile: # 打开文件 student_old = rfile.readlines() # 读取全部内容 else: student_old = [] ifdel = False # 标记是否删除 if student_old: # 如果存在学生信息 with open(filename, 'w') as wfile: # 以写方式打开文件 d = {} # 定义空字典 for list in student_old: d = dict(eval(list)) # 字符串转字典 if d['id'] != studentId: wfile.write(str(d) + "\n") # 将一条学生信息写入文件 else: ifdel = True # 标记已经删除 if ifdel: print("ID为 %s 的学生信息已经被删除..." % studentId) else: print("没有找到ID为 %s 的学生信息..." % studentId) else: # 不存在学生信息 print("无学生信息...") break # 退出循环 show() # 显示全部学生信息 inputMark = input("是否继续删除?(y/n):") if inputMark == "y": mark = True # 继续删除 else: mark = False # 退出删除学生信息功能 '''4 修改学生成绩信息''' def modify(): show() # 显示全部学生信息 if os.path.exists(filename): # 判断文件是否存在 with open(filename, 'r') as rfile: # 打开文件 student_old = rfile.readlines() # 读取全部内容 else: return studentid = input("请输入要修改的学生ID:") with open(filename, "w") as wfile: # 以写模式打开文件 for student in student_old: d = dict(eval(student)) # 字符串转字典 if d["id"] == studentid: # 是否为要修改的学生 print("找到了这名学生,可以修改他的信息!") while True: # 输入要修改的信息 try: d["name"] = input("请输入姓名:") d["english"] = int(input("请输入英语成绩:")) d["python"] = int(input("请输入Python成绩:")) d["c"] = int(input("请输入C语言成绩:")) except: print("您的输入有误,请重新输入。") else: break # 跳出循环 student = str(d) # 将字典转换为字符串 wfile.write(student + "\n") # 将修改的信息写入到文件 print("修改成功!") else: wfile.write(student) # 将未修改的信息写入到文件 mark = input("是否继续修改其他学生信息?(y/n):") if mark == "y": modify() # 重新执行修改操作 '''5 排序''' def sort(): show() # 显示全部学生信息 if os.path.exists(filename): # 判断文件是否存在 with open(filename, 'r') as file: # 打开文件 student_old = file.readlines() # 读取全部内容 student_new = [] for list in student_old: d = dict(eval(list)) # 字符串转字典 student_new.append(d) # 将转换后的字典添加到列表中 else: return ascORdesc = input("请选择(0升序;1降序):") if ascORdesc == "0": # 按升序排序 ascORdescBool = False # 标记变量,为False表示升序排序 elif ascORdesc == "1": # 按降序排序 ascORdescBool = True # 标记变量,为True表示降序排序 else: print("您的输入有误,请重新输入!") sort() mode = input("请选择排序方式(1按英语成绩排序;2按Python成绩排序;3按C语言成绩排序;0按总成绩排序):") if mode == "1": # 按英语成绩排序 student_new.sort(key=lambda x: x["english"], reverse=ascORdescBool) elif mode == "2": # 按Python成绩排序 student_new.sort(key=lambda x: x["python"], reverse=ascORdescBool) elif mode == "3": # 按C语言成绩排序 student_new.sort(key=lambda x: x["c"], reverse=ascORdescBool) elif mode == "0": # 按总成绩排序 student_new.sort(key=lambda x: x["english"] + x["python"] + x["c"], reverse=ascORdescBool) else: print("您的输入有误,请重新输入!") sort() show_student(student_new) # 显示排序结果 ''' 6 统计学生总数''' def total(): if os.path.exists(filename): # 判断文件是否存在 with open(filename, 'r') as rfile: # 打开文件 student_old = rfile.readlines() # 读取全部内容 if student_old: print("一共有 %d 名学生!" % len(student_old)) else: print("还没有录入学生信息!") else: print("暂未保存数据信息...") ''' 7 显示所有学生信息 ''' def show(): student_new = [] if os.path.exists(filename): # 判断文件是否存在 with open(filename, 'r') as rfile: # 打开文件 student_old = rfile.readlines() # 读取全部内容 for list in student_old: student_new.append(eval(list)) # 将找到的学生信息保存到列表中 if student_new: show_student(student_new) else: print("暂未保存数据信息...") # 将保存在列表中的学生信息显示出来 def show_student(studentList): from prettytable import PrettyTable if not studentList: print("(o@.@o) 无数据信息 (o@.@o) \n") return field_names = ("ID", "名字", "英语成绩", "Python成绩", "C语言成绩", "总成绩") table = PrettyTable(field_names=field_names) for info in studentList: sum_score = info.get('english', 0) + info.get('python', 0) + info.get('c', 0) row = list(info.values()) row.append(sum_score) table.add_row(row) print(table) if __name__ == "__main__": main()运行结果示例: 学生信息管理系统 =============== 功能菜单 =============== │ 1 录入学生信息 │ │ 2 查找学生信息 │ │ 3 删除学生信息 │ │ 4 修改学生信息 │ │ 5 排序 │ │ 6 统计学生总人数 │ │ 7 显示所有学生信息 │ │ 0 退出系统 请选择:1 请输入ID(如 1001):1109 请输入名字:浅浅 请输入英语成绩:98 请输入Python成绩:99 请输入C语言成绩:80 是否继续添加?(y/n):n 学生信息录入完毕!!!