函数 function
6.1 pycharm快捷键
Ctrl + P 参数的信息(在方法中调用参数,鼠标放在函数参数括号内)
Ctrl + Q 快速查看文档
def get_color(value):
""" #函数体内输入三个"""回车 写注释
:param value: 参数怎么写
:return: 结果是什么
"""
定义
(1) 用于封装一个特定的功能,表示一个功能或者行为。 (行数不要太多<10)
(2) 函数是可以重复执行的语句块, 可以重复调用。将功能与使用分离
def attack():
print("直拳")
print("摆拳")
print("勾拳")
print("肘击")
print("鞭腿")
#使用
attack() #如果需要调试时进入函数体,按F7,F8调试,不会进入函数体
attack()
6.4 基础语法
6.4.1 定义函数
def 函数名(形式参数):
函数体
函数名(实际参数)
(2) 说明:
def 关键字:全称是define,意为”定义”。
函数名:对函数体中语句的描述,规则与变量名相同。
函数体:完成该功能的语句。
形式参数:函数定义者要求调用者提供的信息。
实际参数:实际使用时传递的参数
(3) 函数的第一行语句建议使用文档字符串描述函数的功能与参数
# 形式参数:表面的不具体的数据
def attack(count):
for __ in range(count):
print("直拳")
print("摆拳")
print("勾拳")
attack(5) #使用5次
定义函数,在终端中打印一维列表.
def print_list(list):
for __ in list:
print(__)
list01 = [5, 546, 6, 56, 76, ]
list02 = [7,6,879,9,909,]
print_list(list01)
print_list(list02)
创建函数,在终端中打印矩形
def print_rectangular(number):
for row in range(number):
if row == 0 or row == number - 1:
print("*" * number)
else:print("*%s*" % (" " * (number - 2)))
print_rectangular(5)
定义函数,实现两个数字相加
"""
函数
设计理念
崇尚小而精,拒绝大而全
返回值
函数定义者给函数调用者传递的结果
"""
# 大而全的函数(获取数据、逻辑计算、显示结果)
def add():
number_one = int(input("请输入第一个数字:"))
number_two = int(input("请输入第二个数字:"))
result = number_one + number_two
print("结果是:%s" % result)
add()
#短而精,功能简化
def add(number_one, number_two):
result = number_one + number_two
return result # 返回数据,不返回数据,将打印不出结果,即为none
data = add(5, 2)
print(data)
6.4.3 返回值
(1) 定义:方法定义者告诉调用者的结果。
(2) 语法:return 数据
(3) 说明:
return后没有语句,相当于返回 None。 函数体没有return,相当于返回None。
"""
函数返回值语法
"""
# 1. 返回结果,接收结果
def func01():
print("func01执行了")
return 100
result = func01()
print(result) #func01执行了 \ 100 接收了函数值
# 2. 调用者也可以不接收结果
func01() #func01执行了
# 3. 无返回值,无return,相当于返回return None
def func02():
print("func02执行了")
data = func02()
print(data) #func02执行了 \ None
# 4. return 可以退出多层循环嵌套
def func04():
while True:
while True:
while True:
# break 只能退出一层循环
print("循环体")
return
data = func04()
print(data) # 循环体 \ None
练习–转换函数
confirmed = int(input("请输入确诊人数:"))
cure = int(input("请输入治愈人数:"))
cure_rate = cure / confirmed * 100
print("治愈比例为" + str(cure_rate) + "%")
################################################
def rate(conf,cure):
cure_rate=cure/conf*100
return cure_rate
res=rate(2,1)
print("治愈比例为" + str(res) + "%") #治愈比例为50.0%
list02 = [5, 1, 4, 6, 7, 4, 6, 8, 5]
max_value = list02[0]
for i in range(1, len(list02)):# 1 2 3 4 .. 总数-1
if max_value < list02[i]:
max_value = list02[i]
print(max_value)
#########################################
def get_max(list_target):
max_value = list_target[0]
for i in range(1, len(list_target)):
if max_value < list_target[i]:
max_value = list_target[i]
return max_value
list02 = [5, 1, 4, 6, 7, 4, 6, 8, 5]
print(get_max(list02))
"""
在终端中获取颜色(RGBA),打印描述信息,否则提示颜色不存在
"R" -> "红色"
"G" -> "绿色"
"B" -> "蓝色"
"A" -> "透明度"
"""
color = input("请输入颜色(RGBA):")
dict_color_info = {
"R": "红色",
"G": "绿色",
"B": "蓝色",
"A": "透明度"
}
# print(dict_color_info[color])
if color in dict_color_info:
print(dict_color_info[color])
else:
print("颜色不存在")
###########################################
def get_color(value):
dict_color_info = {
"R": "红色",
"G": "绿色",
"B": "蓝色",
"A": "透明度"
}
if value in dict_color_info:
return dict_color_info[value]
print(get_color("A"))
使用容器包装需要返回的多个数据
total_liang = int(input("请输入两:"))
jin = total_liang // 16
liang = total_liang % 16
print(str(jin) + "斤零" + str(liang) + "两")
###########################################
def get_weight(total_liang):
""" #"""换行自动填充,注释
获取重量
:param total_liang: 总量数
:return: 元组(斤,两)
"""
jin = total_liang // 16
liang = total_liang % 16
return jin,liang
jin,liang = get_weight(100)
print(str(jin) + "斤零" + str(liang) + "两")
创建函数,根据课程阶段计算课程名称.
number = input("请输入课程阶段数:")
if number == "1":
print("Python语言核心编程")
elif number == "2":
print("Python高级软件技术")
elif number == "3":
print("Web全栈")
elif number == "4":
print("项目实战")
elif number == "5": \
print("数据分析、人工智能")
###########################################
def get_course_name(number):
"""
获取课程名称
:param number: int类型,课程编号
:return: 课程名称
"""
tuple_course=(
"Python语言核心编程",
"Python高级软件技术",
"Web全栈",
"项目实战",
"数据分析、人工智能"
)
return tuple_course[number-1]
print(get_course_name(1))
创建函数,计算IQ等级
ma = int(input("请输入你的心里年龄:"))
ca = int(input("请输入你的实际年龄:"))
iq = ma / ca * 100
if iq>= 140:
print("天才")
elif iq >= 120:
print("超常")
elif iq >= 110:
print("聪慧")
elif iq >= 90:
print("正常")
elif iq >= 80:
print("迟钝")
else:print("低能")
###########################################
def get_iq(ma, ca):
"""
:param ma:
:param ca:
:return:
"""
iq = ma / ca * 100
if 140 <= iq: return "天才" #已经返回结果退出了,跟下面的判断没关系了。简化嵌套
if 120 <= iq: return "超常"
if 110 <= iq: return "聪慧"
if 90 <= iq: return "正常"
if 80 <= iq: return "迟钝"
return "低能"
print(get_iq(18, 40))
多个函数的相互调用
#程序 自上而下运行,重名将会覆盖,运行时,根据调用的位置来使用函数。加断点调试观察
#attack(2) //报错,得先有函数
def attack(c):
print("直拳")
print("摆拳")
#attack(2) //直拳 摆拳 直拳 摆拳
def attack(count):
for __ in range(count):
print("直拳")
attack(2) #直拳 直拳
def attack():
print("直拳")
print("摆拳")
return 1
def re_attack(count):
for __ in range(count):
attack()
print(re_attack(2))
直拳
摆拳
直拳
摆拳
None //前两次是函数的执行,未在re_attcak设置return。返回了None
定义函数,根据年月日计算是天数, 如果2月是闰年,29天。平年,则28
"""
定义函数,根据年月日计算总天数
"""
"""
year = int(input("请输入年份:"))
if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
day = 29
else:
day = 28
month = int(input("请输入月:"))
day = int(input("请输入日:"))
days_of_month = (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
total_days = sum(days_of_month[:month - 1])
total_days += day
print(f"{month}月{day}日是第{total_days}天.")
"""
def get_day_by_month02(year): # 3
"""
获取二月天数
:param year: 年份
:return: 天数
"""
# if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
# return 29
# else:
# return 28
if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
return 29
return 28
# def is_leap_year(year):
# if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
# return True #闰年
# else:
# return False
def get_total_day(year,month,day): # 2
"""
获取总天数
:param year: 年份
:param month: 月份
:param day: 日
:return: 总天数
"""
day_of_month02 = get_day_by_month02(year)
days_of_month = (31, day_of_month02, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
total_days = sum(days_of_month[:month - 1])
total_days += day
return total_days
print(get_total_day(2021,5,12)) # 132
函数的内存分布
#1、将函数代码加载到内存中,函数体不执行
def func01():
a=10
print("func01执行了")
#2、调用函数,在内存中开辟空间(栈帧),存储在函数内部创建的变量
func01()
#3、函数执行后,内存空间立即释放
6.5 可变/不可变类型在传参时的区别
(1) 不可变类型参数有:
数值型(整数,浮点数)、布尔值bool、None 空值、字符串str、元组tuple
(2) 可变类型参数有: 列表 list、字典 dict、集合 set
(3) 传参说明:
不可变类型的数据传参时,函数内部不会改变原数据的值。
可变类型的数据传参时,函数内部可以改变原数据。取值定义[ ]=时,改变
def func01(p1, p2):
p1 = "孙悟空"
p2["八戒"] += 50
a = "悟空"
b = {"八戒": 100}
func01(a, b) #函数执行,转瞬即逝
print(a) # 悟空,不可变
print(b) # 150,字典键对应的值+50,可变
def func01(p1, p2):
p1 = [100, 200] # p1在pycharm显示灰色,函数外没有结果,虽然传入的是可变数据
p2[:] = [300, 400] #切片,遍历后面的可迭代对象
a = [10, 20]
b = [30, 40]
func01(a, b)
print(a) # [10, 20]
print(b) # [300, 400]
根据下列代码,创建降序排列函数。
def descending_order(list01):
for r in range(len(list01) - 1):
for c in range(r + 1, len(list01)):
if list01[r] < list01[c]:
list01[r], list01[c] = list01[c], list01[r]
# return list01 不需要返回,[]已经产生了修改
#传入可变对象list01,产生修改list01[r],满足后就不需要rerun返回数据
list01 = [4, 45, 565, 54, 56, ]
descending_order(list01)
print(list01) # 排序结果在列表,不在返回值
定义函数,将列表中大于某个值的元素设置为None
参数 结果
[34, 545, 56, 7, 78, 8] -10 -> [None,None,None,7,None,8]
[34, 545, 56, 7, 78, 8] -100 -> [34, None, 56, 7, 78, 8]
def update_data(list_target,value):
for i in range(len(list_target)):
if list_target[i] > value:
list_target[i] = None
list01=[34, 545, 56, 7, 78, 8]
update_data(list01,10)
print(list01)
def func01(p1, p2,p3):
print(p1)
print(p2)
print(p3)
func01(1,2,3) #位置实参,根据顺序与形参进行对应
func01(p1=1,p3=3,p2=2) #关键字实参,根据形参名字对应,可以不按顺序
缺省形参
缺省参数必须自右至左依次存在,如果一个参数有缺省参数,则其右侧的所有参数都必须有缺省参数。
def func02(p1=0,p2=0,p3=0): #默认形参:实参可选,也可不填
print(p1)
print(p2)
print(p3)
func02(1,2,3)
func02(1,2) #默认形参:实参可选,也可不填
func02(p2=2)
func02(1,p3=3) #也可以混用,注意位置参数在前
6.7 作用域LEGB
6.7.1 定义
变量起作用的范围。
6.7.2 分类
(1) Local局部作用域:函数内部。def fun():
(2) Enclosing 外部嵌套作用域 :函数嵌套。
(3) Global全局作用域:模块(.py文件)内部。
(4) Builtin内置模块作用域:builtins.py文件 print int ...
6.7.3 变量名的查找规则
(1) 由内到外:L -> E -> G -> B
(2) 在访问变量时,先查找本地变量,然后是包裹此函数外部的函数内部的变量,之后是全局变量,最后是内置变量。
6.7.4 局部变量
(1) 定义在函数内部的变量(形参也是局部变量)
(2) 只能在函数内部使用
(3) 调用函数时才被创建,函数结束后自动销毁
6.7.5 全局变量
(1) 定义在函数外部,模块内部的变量。
(2) 在整个模块(py文件)范围内访问(但函数内不能将其直接赋值)。
6.7.6 global 语句
(1) 作用:在函数内部修改全局变量。在函数内部定义全局变量(全局声明)。
(2) 语法:global 变量1, 变量2, …
(3) 说明
在函数内直接为全局变量赋值,视为创建新的局部变量。
不能先声明局部的变量,再用global声明为全局变量。
6.7.7 nonlocal 语句
(1) 作用:在内层函数修改外层嵌套函数内的变量
(2) 语法:nonlocal 变量名1,变量名2, ...
(3) 说明:在被嵌套的内函数中进行使用
# 2. 全局作用域:文件内部。全局变量:在全部作用域内创建的变量。 适用范围:整个文件
data02 = 20
data03 = [30]
def func01(): # 1. 局部作用域:函数内部 # 局部变量:在局部作用域内创建的变量
data01 = 10
print(data01)
print(data02)
def func02(): # print(data01) # 不能访问其他函数局部变量
print(data02) # 读取全局变量
def func03(): # 在局部作用域中不能修改全局变量 # data02 = 200 # 必须通过global语句声明
global data02
data02 = 200 #灰色无效
def func04(): # 没有修改全局变量,修改全局变量指向的列表。所以不需要通过global语句声明
data03[0] = 300
func01() # 10 20
func02() # 20
func03()
func04()
print(data02) # 200
print(data03) # [300]
根据下列代码,创建函数。实现输入1,2,3,4 执行对应的函数
########################全局变量################################
dict_commodity_infos = {
1001: {"name": "屠龙刀", "price": 10000},
1002: {"name": "倚天剑", "price": 10000},
1003: {"name": "金箍棒", "price": 52100},
1004: {"name": "口罩", "price": 20},
1005: {"name": "酒精", "price": 30},
}
# 订单列表
list_orders = [
{"cid": 1001, "count": 1},
{"cid": 1002, "count": 3},
{"cid": 1005, "count": 2},
]
########################定义函数################################
# 1.定义函数,打印所有商品信息,
def print_all_commodity():
for cid, info in dict_commodity_infos.items():
print("商品编号%d,商品名称%s,商品单价%d." % (cid, info["name"], info["price"]))
# 2. 定义函数,打印单价大于10000的商品信息,
def print_commodity_price_gt_10000():
for cid, info in dict_commodity_infos.items():
if info["price"] > 10000:
print("商品编号%d,商品名称%s,商品单价%d." % (cid, info["name"], info["price"]))
# 3. 定义函数,查找数量最多的订单(使用自定义算法,不使用内置函数)
def max_order_by_count():
max_value = list_orders[0]
for i in range(1, len(list_orders)):
if max_value["count"] < list_orders[i]["count"]:
max_value = list_orders[i]
return max_value
# 4. 定义函数,根据购买数量对订单列表降序(大->小)排列
def descending_order():
# list_orders[0] = 10 # 通过全局变量修改列表
# list_orders = 10 # 修改全局变量
for r in range(len(list_orders) - 1):
for c in range(r + 1, len(list_orders)):
if list_orders[r]["count"] < list_orders[c]["count"]:
list_orders[r], list_orders[c] = list_orders[c], list_orders[r]
########################入口代码################################
item = int(input("请输入选项:"))
if item == 1:
print_all_commodity()
elif item == 2:
print_commodity_price_gt_10000()
elif item == 3:
order = max_order_by_count()
# print("数量最多的订单是:"+str(order))
print("订单编号是:%s,数量是%s" % (order["cid"], order["count"]))
elif item == 4:
descending_order()
print(list_orders)
函数形参
"""
函数参数
形式参数
星号元组形参
双星号字典形参
"""
# 实参数量无限
# -- 只支持位置实参
def func01(*p1): # 多 合 一(元组)
print(p1)
func01(1,2,3) #(1, 2, 3)
#定义函数,数值累乘
def multiplicative(*args):
result =1
for item in args:
result *=item
return result
print(multiplicative(2,3,4))
# -- 只支持关键字实参
def func02(**p1): # 多 合 一(字典)
print(p1)
func02()
func02(p1=1, p2=2) # {'p1': 1, 'p2': 2}
def func03(*args, **kwargs):
print(args)
print(kwargs)
func03(1, 2, 3) # (1, 2, 3)
func03(p1=1, p2=2) # {'p1': 1, 'p2': 2}
func03(1, 2, 3, p1=1, p2=2) # (1, 2, 3){'p1': 1, 'p2': 2}
# 实参顺序:先位置再关键字
# func03(1, 2, p1=1, 3, p2=2)
# func03(p1=1, p2=2, 1, 2, 3)
# --------------------------数据--------------------------
# 字典优点:定位单个元素最快/方便
# 擅长:存储多个维度信息,例如:商品信息、员工信息
# 列表优点:有顺序,定位元素最灵活(索引/切片)
# 擅长:存储单一维度信息,例如:所有商品、所有员工
# 商品列表
# dict_commodity_infos = {
# 1001:{"name": "屠龙刀", "price": 10000},
# 1002:{"name": "倚天剑", "price": 10000},
# 1003:{"name": "金箍棒", "price": 52100},
# 1004:{"name": "口罩", "price": 20},
# 1005:{"name": "酒精", "price": 30},
# }
list_commodity_infos = [
# [1001,"屠龙刀",10000],
{"cid": 1001, "name": "屠龙刀", "price": 10000},
{"cid": 1002, "name": "倚天剑", "price": 10000},
{"cid": 1003, "name": "金箍棒", "price": 52100},
{"cid": 1004, "name": "口罩", "price": 20},
{"cid": 1005, "name": "酒精", "price": 30},
]
# 订单列表
list_orders = [
{"cid": 1001, "count": 1},
{"cid": 1002, "count": 3},
{"cid": 1005, "count": 2},
]
# 1. 打印所有商品信息,格式:商品编号xx,商品名称xx,商品单价xx.
for commodity in list_commodity_infos:
print(f"编号:{commodity['cid']},商品名称:{commodity['name']},商品单价:{commodity['price']}")
# print(f"编号:{commodity[0]},商品名称:{commodity[1]},商品单价:{commodity[2]}")
# 2. 打印商品单价小于2万的商品信息
for commodity in list_commodity_infos:
if commodity["price"] < 20000:
print(f"编号:{commodity['cid']}商品名称:{commodity['name']}商品单价:{commodity['price']}")
# 3. 定义函数,打印所有订单中的商品信息,
# 格式:商品名称xx,商品单价:xx,数量xx.
for order in list_orders: # 遍历所有订单
for commodity in list_commodity_infos: # 遍历所有商品信息
if order["cid"] == commodity["cid"]:
print(f"商品名称{commodity['name']},商品单价:{commodity['price']},数量{order['count']}.")
break
# 4. 查找单价最高的商品
max_value = list_commodity_infos[0]
for i in range(1, len(list_commodity_infos)):
if max_value["price"] > list_commodity_infos[i]["price"]:
max_value = list_commodity_infos[i]
print(max_value)
# 5. 根据单价升序排列
for r in range(len(list_commodity_infos) - 1):
for c in range(r + 1, len(list_commodity_infos)):
if list_commodity_infos[r]["price"] < list_commodity_infos[c]["price"]:
list_commodity_infos[r], list_commodity_infos[c] = list_commodity_infos[c], list_commodity_infos[r]
"""
参照下列代码,定义函数,计算社保缴纳费用.
salary_before_tax = float(input("请输入税前工资:"))
social_insurance = salary_before_tax * (0.08 + 0.02 + 0.002 + 0.12) + 3
print("个人需要缴纳社保费用:" + str(social_insurance))
"""
# 核心设计思想:崇尚小而精 拒绝大而全
def get_social_insurance(base_pay):
"""
获取社保缴纳费用
:param base_pay: 底薪
:return:社保缴纳费用
"""
# print(结果) 显示给用户
# return 结果 返回给程序员
return 3 + base_pay * (0.08 + 0.002 + 0.02 + 0.12)
# 测试
print(get_social_insurance(50000))
"""
定义函数,在列表中获取最小值
list01 = [170, 160, 180, 165]
min_value = list01[0]
for i in range(1, len(list01)):
if min_value > list01[i]:
min_value = list01[i]
print(min_value)
"""
def get_min(list_target):
"""
获取最小值
:param list_target:list类型,目标列表
:return:最小值
"""
min_value = list_target[0]
for i in range(1, len(list_target)):
if min_value > list_target[i]:
min_value = list_target[i]
return min_value
list01 = [170, 160, 180, 165]
list02 = [45,43,55,6,7]
res = get_min(list01)
res = get_min(list02)
print(res)
|