函数概述
从实现函数的角度来看,其至少需要想清楚以下 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: 是否登录成功
"""
pass
login('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 = 500
print(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 = 100
operator = []
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 num2
print(mymax(1, 2))
mypow = lambda x, y=2 : x**y
print(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 PrettyTable
def 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 * ... * n
def factorial(num):
"""通过递归的方式求num的阶乘"""
#递归退出的条件: num <= 1
#阶乘循环的内容: num! = num * (num-1)!
if num > 1:
result = num * factorial(num-1)
else:
result = 1
return result
if __name__ == '__main__':
print("2的阶乘: ", factorial(2))
print("3的阶乘: ", factorial(3))
print("4的阶乘: ", factorial(4))
递归实现Fib
from functools import lru_cachebr/>@lru_cache(maxsize=1000)
def fib(num):
#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 = 0
def 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
学生信息录入完毕!!!
来源:51CTO
作者:霍金181
链接:https://blog.51cto.com/13810716/2457490