pt03-function&传参

function

pycharm快捷键

Ctrl + P 参数的信息(在方法中调用参数,鼠标放在函数参数括号内)
Ctrl + Q 快速查看文档

def get_color(value):
    """          #函数体内输入三个"""回车  写注释
    
    :param value:  参数怎么写
    :return:    结果是什么
    """

function

(1) 用于封装一个特定的功能,表示一个功能或者行为。    (行数不要太多<10)
(2) 函数是可以重复执行的语句块, 可以重复调用。将功能与使用分离
def attack():
    print("直拳")
    print("摆拳")
    print("勾拳")
    print("肘击")
    print("鞭腿")
#使用  
attack()   #如果需要调试时进入函数体,按F7,F8调试,不会进入函数体
attack()

定义函数

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  
# 返回结果,不打印,看不到但是可以被接收使用,print的数据,可以看到,但是不能被程序使用

data = add(5, 2)
print(data)   # 打印出 7  ,若注释return,将打印出 none

返回值return

(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 "ok"
def re_attack(count):
    for __ in range(count):
       attack()

print(re_attack(2))
直拳
摆拳
直拳
摆拳
None //前两次是函数的执行,未在re_attcak设置return。返回了一个None

函数定义的先后顺序,不影响函数的调用(调用需在定义之后)。

def re_attack(count):  # 2
    list_result = []
    for __ in range(count):
        result = attack()
        list_result.append(result)
    return list_result

def attack():  # 3
    print("直拳")
    print("摆拳")
    return "ok"

# ---------------调用函数--------------------
state = re_attack(2)  # 1
print(state)  #

直拳
摆拳
直拳
摆拳
['ok', 'ok']

定义函数,根据年月日计算是天数, 如果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、函数执行后,内存空间立即释放

可变/不可变类型在传参时的区别

(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 set_none_gt_value(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]
set_none_gt_value(list01, 10)
print(list01)

list01 = [34, 545, 56, 7, 78, 8]
set_none_gt_value(list01, 100)
print(list01)

作用域LEGB

变量起作用的范围。

分类

(1) Local局部作用域:函数内部。def fun():
(2) Enclosing 外部嵌套作用域 :函数嵌套。
(3) Global全局作用域:模块(.py文件)内部。
(4) Builtin内置模块作用域:builtins.py文件     print  int ...  鼠标放print上Ctrl+鼠标左键查看

变量名的查找规则

(1) 由内到外:L -> E -> G -> B
(2) 在访问变量时,先查找本地变量,然后是包裹此函数外部的函数内部的变量,之后是全局变量,最后是内置变量。

局部变量

(1) 定义在函数内部的变量(形参也是局部变量)
(2) 只能在函数内部使用
(3) 调用函数时才被创建,函数结束后自动销毁

全局变量

(1) 定义在函数外部,模块内部的变量。
(2) 在整个模块(py文件)范围内访问(但函数内不能将其直接赋值)。

global 语句

(1) 作用:在函数内部修改全局变量。在函数内部定义全局变量(全局声明)。 
(2) 语法:global 变量1, 变量2, …
(3) 说明
在函数内直接为全局变量赋值,视为创建新的局部变量。
不能先声明局部的变量,再用global声明为全局变量。

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   #pycharm里data02灰色,无效,没有被使用,加一行print使用,变成黑色
    
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"]))

"""
------------将重复的操作定义为函数再使用--------------
"""
def print_commodity(cid,info):
    print("商品编号%d;商品名称%s;商品单价%d." % (cid, info["name"], info["price"]))

# 1.定义函数,打印所有商品信息,
def print_commoditys():
    for cid, info in dict_commodity_infos.items():
        # print("商品编号%d;商品名称%s;商品单价%d." % (cid, info["name"], info["price"]))
        print_commodity(cid,info)

# 2. 定义函数,打印单价大于10000的商品信息
def print_commoditys_gt_1w():
    for cid, info in dict_commodity_infos.items():
        if info["price"] > 10000:
            # print("商品编号%d;商品名称%s;商品单价%d." % (cid, info["name"], info["price"]))
            print_commodity(cid, info)
# 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_by_count():
    # 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]
                
# ------------调用--------------
# 调用无返回值函数
print_commoditys()
print_commoditys_gt_1w()
# 调用有返回值函数,接收返回值打印
order = get_max_by_count()
print(order)
# 函数内部修改可变数据,在函数外直接访问可变数据
descending_order_by_count()
print(list_orders) 
"""

account_type = input("请输入账户类型:")
money = float(input("请输入消费金额:"))
if account_type == "vip":
    if money < 500:
        print("享受85折扣")
    else:
        print("享受8折扣")
else:
    if money > 800:
        print("享受9折扣")
    else:
        print("原价购买")

"""

# def get_discount(account_type,money):
#     if account_type == "vip":
#         if money < 500:
#             return 0.85
#         else:
#             return 0.8
#     else:
#         if money > 800:
#             return 0.9
#         else:
#             return 1

def get_discount(account_type, money):
    """
    :param account_type:  用户类型
    :param money: 多少钱
    :return: 折扣
    """
    if account_type == "vip":
        return 0.85 if money < 500 else 0.8
    return 0.9 if money > 800 else 1

print(get_discount("vip", 1000))	#0.8	
print(get_discount("other", 1000))  #0.9
"""
    定义函数,在列表中获取最小值
    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]
res = get_min(list01)
print(res)

list02 = [45, 43, 55, 6, 7]
print(get_min(list02))
# ---------------全局变量(数据)-------------
dict_employees = {
    1001: {"did": 9002, "name": "师父", "money": 60000},
    1002: {"did": 9001, "name": "孙悟空", "money": 50000},
    1003: {"did": 9002, "name": "猪八戒", "money": 20000},
    1004: {"did": 9001, "name": "沙僧", "money": 30000},
    1005: {"did": 9001, "name": "小白龙", "money": 15000},
}

list_departments = [
    {"did": 9001, "title": "教学部"},
    {"did": 9002, "title": "销售部"},
    {"did": 9003, "title": "品保部"},
]


# ---------------函数(操作)-------------
def print_single_employee(eid, emp):
    print(f"{emp['name']}的员工编号是{eid},部门编号是{emp['did']},月薪{emp['money']}元.")


# 1. 打印所有员工信息,
# 格式:xx的员工编号是xx,部门编号是xx,月薪xx元。
def print_employees():
    for eid, emp in dict_employees.items():
        # print(f"{emp['name']}的员工编号:{emp['eid']},部门编号是{emp['did']},月薪{emp['money']}元.")
        print_single_employee(eid, emp)


# 2. 打印所有月薪大于2w的员工信息,
# 格式:xx的员工编号是xx,部门编号是xx,月薪xx元.
def print_employees_gt_20000():
    for eid, emp in dict_employees.items():
        if emp['money'] > 20000:
            # print(f"{emp['name']}的员工编号:{emp['eid']},部门编号是{emp['did']},月薪{emp['money']}元.")
            print_single_employee(eid, emp)


# 3. 在部门列表中查找编号最小的部门
def get_min_by_did():
    min_value = list_departments[0]
    for i in range(1, len(list_departments)):
        if min_value["did"] > list_departments[i]["did"]:
            min_value = list_departments[i]
    return min_value


# 4. 根据部门编号对部门列表升序排列
def descending_order_by_did():
    for r in range(len(list_departments) - 1):  # 0
        for c in range(r + 1, len(list_departments)):  # 1234
            if list_departments[r]["did"] > list_departments[c]["did"]:
                list_departments[r], list_departments[c] = list_departments[c], list_departments[r]


# ---------------入口(使用)-------------
print_employees()

print(get_min_by_did())

descending_order_by_did()
print(list_departments)
#不能直接print(descending_order_by_did()),descending_order_by_did()不返回结果,直接修改list
def calculating_life_stages(age):
    """

    :param age:
    :return:
    """
    if age <= 6: return "童年"
    if age <= 17: return "少年"
    if age <= 40: return "青年"
    if age <= 65: return "中年"
    return "老年"


stages = calculating_life_stages(15)
print(stages)

函数参数

实际参数

"""
    函数参数
        实际参数
            位置实参
            关键字实参
"""

def func01(p1, p2, p3):
    print(p1)
    print(p2)
    print(p3)

func01(1, 2, 3)  # 位置实参:按顺序与形参进行对应
func01(p2=2, p1=1, p3=3)   # 关键字实参:按名字与形参进行对应

形式参数

默认形参:实参可选 注意:必须从右向左依次存在

"""
    函数参数
        形式参数
            默认形参
            位置形参
"""

# 默认形参:实参可选  注意:必须从右向左依次存在
def func01(p1=False, p2="", p3=0):
    print(p1)
    print(p2)
    print(p3)

func01()      #0
func01(True)    # True  0
func01(True, "a", 10)	#True  a 10

# 位置形参:实参必填
def func02(p1,p2,p3):
    print(p1)
    print(p2)
    print(p3)

func01(1,2,3)   	    #位置实参,根据顺序与形参进行对应
func01(p1=1,p3=3,p2=2)	#关键字实参,根据形参名字对应,可以不按顺序

练习

"""
    定义函数,根据小时、分钟、秒,计算总秒数
    调用:提供小时、分钟、秒
    调用:提供分钟、秒
    调用:提供小时、秒
    调用:提供分钟
"""


def get_total_second(hour=0, minute=0, second=0):
    return hour * 3600 + minute * 60 + second


print(get_total_second(1, 2, 3))
print(get_total_second(minute=2, second=3))
print(get_total_second(1, second=3))
print(get_total_second(minute=2))

不定长参数

星号元组形参
"""
    函数参数
        形式参数
            不定长形参:实参数量无限
                优点:调用者方便(不用自行构建容器)
                星号元组形参
                双号字典形参
"""
# 星号元组形参:将多个位置实参合并为一个元组。 价值:位置实参数量无限
def func01(*p1):
    print(p1)
    
func01()    #()
func01(10)    #(10,)
func01(10,20)   #(10,20)
func01(p1 = 1) # 不支持关键字实参
双号字典形参
# 双号字典形参:将多个关键字实参合并为一个字典
# 价值:关键字实参数量无限
def func02(**p1):
    print(p1)


func02(a=1,b=2)# 只支持关键字实参
func02(1,2)  {'a': 1, 'b': 2}
练习 数值累乘
"""
    练习:定义数值累乘的函数 
"""

# 由定义者自动构建容器
def multiplicative(*args):  # (13,34,54,56,56,77)
    result = 1
    for item in args:
        result *= item
    return result


print(multiplicative(13, 34, 54, 56, 56, 77))

"""不使用元组形参,不建议
def multiplicative(args):
    result = 1
    for item in args:
        result *= item
    return result

# 由调用者构建容器(调用者麻烦)
list_number = [13, 34, 54]
print(multiplicative(list_number))
"""

序列实参

"""
    函数参数
        实际参数
            序列实参
            字典实参
            共同作用:将容器的元素传入函数
"""


def func01(p1, p2, p3):
    print(p1)
    print(p2)
    print(p3)


data01 = [1, 2, 3]
data02 = (1, 2, 3)
data03 = "孙悟空"
data04 = "孙悟空空"

func01(*data01)  # 拆分,# 序列实参:将一个序列拆分为多个实参,按顺序与形参对应
func01(*data01)  # 1 2 3
func01(*data02)  # 1 2 3
func01(*data03)  # 孙 悟 空
func01(*data04)  # 报错多参数了


def func02(*args):  # 这个*作用合并
    print(args)

# 作用:将容器的元素传入函数
list01 = [1, 2, 3, 4]  # 容器构建过程是未知的
func02(*list01)  # 这个*拆分list,执行合并打印出元组(1, 2, 3, 4)

字典实参

def func01(p1, p2, p3):
    print(p1)
    print(p2)
    print(p3)

data04 = {"p2": 2, "p1": 1, "p3": 3}
# 字典实参:将一个字典拆分为多个实参,按名字与形参对应
func01(**data04)  # 1 2 3
func01(*data04)   # p2 p1 p3
命名关键字形参
"""
    函数参数
        形式参数
            命名关键字形参: 增加代码可读性  * 之后的均要命名关键字
"""

# 命名关键字形参p1:实参传递必须是关键字实参
def func01(*args, p1=0):
    print(args)
    print(p1)

func01(1, 2, 3,4)  # (1, 2, 3, 4)  0
func01(1, 2, 3, p1=4)  # (1, 2, 3) 4

# 命名关键字形参p2, 这里*, p2=0,起到命名作用
def func02(p1, *, p2=0):
    print(p1)
    print(p2)


func02(1)    # 1 0 
func02(1, p2=2)  # 1 2
func02(1, 1,p2=2) #报错多参数



# 如果没有命名关键字技术,会出现下列语法现象, 导致代码可读性偏差
print("a", "b", "c", sep="_", end=" ")
print("a", "b", "c", end=" ", sep="_")
print("a", "b", "c", "_", " ")

练习

def func01(list_target): 
    print(list_target)# ? 
def func02(*args): 
    print(args)# ? 
def func03(*args,**kwargs): 
    print(args)# ? 
    print(kwargs)# ? 
def func04(p1,p2,*,p4,**kwargs): 
    print(p1)# ? 
    print(p2)# ? 
    print(p4)# ?
    print(kwargs)# ? 
    
func01([1,2,3])  #打印出列表
func02(*[1,2,3]) #打印元组(1,2,3)
func03(1,2,3,a=4,b=5,c=6) # (1, 2, 3) {'a': 4, 'b': 5, 'c': 6}
func04(10,20,p4 = 30,p5 = 40) #10 20 30 {'p5': 40}

函数参数类型总结

"""
    函数参数
        形式参数:限制实参:1、2给不给,3、4给多少,5怎么给
            1.位置形参:实参必填
                    def 函数名(参数1,参数2)
            2.默认形参:实参可选
                    def 函数名(参数1=数据,参数2=数据)
            3.星号元组形参:位置实参数量无限 
                    def 函数名(*参数)
            4.双星号字典形参:关键字实参数量无限 
                    def 函数名(**参数)
            5.命名关键字形参:必须关键字实参
                    def 函数名(*参数1,参数2)
                    def 函数名(*,参数2)

        实际参数:与形参进行对应
            6.位置实参:按顺序
                    函数名(数据1,数据2)
                8.序列实参:拆,用元素
                    函数名(*序列)
            7.关键字实参:按名字
                    函数名(参数1=数据,参数2=数据)
                9.字典实参:拆,用键值对
                        函数名(**字典)

练习

# ---------------全局变量(数据)-------------
# 员工列表(员工编号 部门编号 姓名 工资)
# 字典:根据key查找值最快,最方便
# 列表:有顺序,查找元素最灵活(索引,切片)
list_employees = [
    {"eid": 1001, "did": 9002, "name": "师父", "money": 60000},
    {"eid": 1002, "did": 9001, "name": "孙悟空", "money": 50000},
    {"eid": 1003, "did": 9002, "name": "猪八戒", "money": 20000},
    {"eid": 1004, "did": 9001, "name": "沙僧", "money": 30000},
    {"eid": 1005, "did": 9001, "name": "小白龙", "money": 15000},
]

# ---------------函数(操作)-------------
def print_single_employee(emp):
    print(f"{emp['name']}的员工编号是{emp['eid']},部门编号是{emp['did']},月薪{emp['money']}元.")

# 1. 打印所有员工信息,
# 格式:xx的员工编号是xx,部门编号是xx,月薪xx元。
def print_employees():
    for emp in list_employees:
        # print(f"{emp['name']}的员工编号是{emp['eid']},部门编号是{emp['did']},月薪{emp['money']}元.")
        print_single_employee(emp)

# 2. 打印所有月薪大于2w的员工信息,
# 格式:xx的员工编号是xx,部门编号是xx,月薪xx元.
def print_employees_gt_20000():
    for emp in list_employees:
        if emp['money'] > 20000:
            # print(f"{emp['name']}的员工编号是{emp['eid']},部门编号是{emp['did']},月薪{emp['money']}元.")
            print_single_employee(emp)


# ---------------入口(使用)-------------
print_employees()

重构如下函数

"""
    重构: 不改变功能,修改内部代码.
    --修改命名
    --修改结构(你想传递的思想是什么?)
    注意:隐藏实现细节,彰显程序过程
"""
shang_pin_info = {
    101: {"name": "屠龙刀", "price": 10000},
    102: {"name": "倚天剑", "price": 10000},
    103: {"name": "九阴白骨爪", "price": 8000},
    104: {"name": "九阳神功", "price": 9000},
    105: {"name": "降龙十八掌", "price": 8000},
    106: {"name": "乾坤大挪移", "price": 10000}
}

ding_dan = []


def gou_wu():
    while True:
        item = input("1键购买,2键结算。")
        if item == "1":
            for key, value in shang_pin_info.items():
                print("编号:%d,名称:%s,单价:%d。" % (key, value["name"], value["price"]))
            while True:
                cid = int(input("请输入商品编号:"))
                if cid in shang_pin_info:
                    break
                else:
                    print("该商品不存在")
            count = int(input("请输入购买数量:"))
            ding_dan.append({"cid": cid, "count": count})
            print("添加到购物车。")
        elif item == "2":
            zong_jia = 0
            for item in ding_dan:
                shang_pin = shang_pin_info[item["cid"]]
                print("商品:%s,单价:%d,数量:%d." % (shang_pin["name"], shang_pin["price"], item["count"]))
                zong_jia += shang_pin["price"] * item["count"]
            while True:
                qian = float(input("总价%d元,请输入金额:" % zong_jia))
                if qian >= zong_jia:
                    print("购买成功,找回:%d元。" % (qian - zong_jia))
                    ding_dan.clear()
                    break
                else:
                    print("金额不足.")


gou_wu()

# 体现过程,隐藏实现。

# 数据
dict_commodity_info = {
    101: {"name": "屠龙刀", "price": 10000},
    102: {"name": "倚天剑", "price": 10000},
    103: {"name": "九阴白骨爪", "price": 8000},
    104: {"name": "九阳神功", "price": 9000},
    105: {"name": "降龙十八掌", "price": 8000},
    106: {"name": "乾坤大挪移", "price": 10000}
}

list_order = [{"cid": 101, "count": 2}]


def shopping():
    while True:
        item = input("1键购买,2键结算。")
        if item == "1":
            buying()
        elif item == "2":
            settlement()


def settlement():
    """
        结算
    """
    print_orders_info()
    total_price = calculate_total_price()
    paying(total_price)


def paying(total_price):
    """
        支付
    :param total_price: 需要支付的金额
    """
    while True:
        money = float(input("总价%d元,请输入金额:" % total_price))
        if money >= total_price:
            print("购买成功,找回:%d元。" % (money - total_price))
            list_order.clear()
            break
        else:
            print("金额不足.")


def calculate_total_price():
    """
        计算总价格
    :return: 总价格
    """
    total_price = 0
    for order in list_order:
        commodity = dict_commodity_info[order["cid"]]
        total_price += commodity["price"] * order["count"]
    return total_price


def print_orders_info():
    """
        打印所有订单信息
    """
    for item in list_order:
        commodity = dict_commodity_info[item["cid"]]
        print("商品:%s,单价:%d,数量:%d." % (commodity["name"], commodity["price"], item["count"]))


def buying():
    """
        购买
    """
    print_commodity_info()
    order = create_order()
    list_order.append(order)
    print("添加到购物车。")


def input_commodity_id():
    """
        获取商品编号
    :return: int类型,商品编号
    """
    while True:
        cid = int(input("请输入商品编号:"))
        if cid in dict_commodity_info:
            return cid
        print("该商品不存在")


def create_order():
    """
        创建订单
    :return: 字典类型的订单
    """
    cid = input_commodity_id()
    count = int(input("请输入购买数量:"))
    order = {"cid": cid, "count": count}
    return order


def print_commodity_info():
    """
        打印商品信息
    """
    for key, value in dict_commodity_info.items():
        print("编号:%d,名称:%s,单价:%d。" % (key, value["name"], value["price"]))


shopping()    #ctrl+鼠标左键点函数,跳转到定义函数的位置看到shopping函数里面调用buying、settlement
再去点击这两个函数,查看干了什么,一点一点弄懂操作了哪些。
项目中可能会有更多的函数,学习类class可以将这些函数归纳分组,可读、分析、构建性更顺利

你可能感兴趣的:(python,python,开发语言)