【Python 基础】Python全栈体系(四)

Python 基础

第五章 函数

一、定义

  1. 用于封装一个特定的功能,表示一个功能或者行为。
  2. 函数是可以重复执行的语句块, 可以重复调用。

二、作用

  • 提高代码的可重用性和可维护性(代码层次结构更清晰)。

三、定义函数

  1. 语法:
    def 函数名(形式参数):
         函数体
    
  2. 说明:
    def 关键字:全称是define,意为”定义”。
    函数名:对函数体中语句的描述,规则与变量名相同。
    形式参数:方法定义者要求调用者提供的信息。
    函数体:完成该功能的语句。
  3. 函数的第一行语句建议使用文档字符串描述函数的功能与参数。

四、调用函数

  1. 语法:函数名(实际参数)
  2. 说明:根据形参传递内容。

五、返回值

  1. 定义:
    方法定义者告诉调用者的结果。
  2. 语法:
    return 数据
  3. 说明:
    return后没有语句,相当于返回 None。
    函数体没有return,相当于返回None。

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

  1. 不可变类型参数有:
    数值型(整数,浮点数,复数)
    布尔值bool
    None 空值
    字符串str
    元组tuple
    固定集合frozenset
  2. 可变类型参数有:
    列表 list
    字典 dict
    集合 set
  3. 传参说明:
    不可变类型的数据传参时,函数内部不会改变原数据的值。
    可变类型的数据传参时,函数内部可以改变原数据。
"""
    函数-参数
    练习:exercise01
"""

def attack():
    """
        攻击函数
    """
    print("侧踹")
    print("直拳")
    print("摆拳")
    print("勾拳")
    print("肘击")

# attack()
# ...
attack()

# 有参数函数
# 形式参数
def attack_repeat(count):
    """
        重复攻击
    :param count:int类型,重复的次数 
    """
    for i in range(count):
        print("侧踹")
        print("直拳")
        print("摆拳")
        print("勾拳")
        print("肘击")

# 实际参数
attack_repeat(3)

"""
print("直拳")
print("摆拳")
print("勾拳")
print("肘击")
#.......
print("直拳")
print("摆拳")
print("勾拳")
print("肘击")
#.......
print("直拳")
print("摆拳")
print("勾拳")
print("肘击")
"""
"""
将下列代码,定义到函数中,打印矩形。
	for r in range(3):
        for c in range(5):
            print("*", end=" ")
        print()
"""


def print_rectangle(r_count,c_count,char):
    for r in range(r_count):
        for c in range(c_count):
            print(char, end=" ")
        print()

print_rectangle(5,3,"*")
print_rectangle(2,7,"#")
"""
    函数-返回值
"""
def fun01():
    print("fun01执行喽")
    return 100 # 返回100

number = fun01()
print(number)

def fun02():
    print("fun01执行喽")
    # return # return关键字后面如果没有数据,相当于返回None
    # 如果函数没有返回值,也相当于返回None

re = fun02()
print(re)

# 即使有返回值,调用者仍然可以不使用变量来接受。
fun01()
"""
    函数-应用
"""


# 函数:封装一个特定功能,表示一个行为。
#      小而精
# 两个数值相加功能
# def add():
#     number_one = float(input("请输入第一个数据:"))
#     number_two = float(input("请输入第二个数据:"))
#     result = number_one + number_two
#     print("结果是:" + str(result))
#
# add()

def add(number_one, number_two):
    return number_one + number_two

result = add(5, 2)
"""
    定义函数,计算多位整数每位相加和.
    输入:12345
    输出:15
"""
def each_unit_sum(number):
    """
        计算整数的每位相加和
    :param number:需要操作的数据,int类型
    :return:相加的结果,int类型
    """
    sum_value = 0
    for item in str(number):
        sum_value += int(item)
    return sum_value

re = each_unit_sum(12345)
print(re)
"""
    定义函数,根据成绩计算等级。
    输入:96
    输出:优秀
"""


# def get_score_level(score):
#     if score < 0 or score > 100:
#         return "成绩输入有误"
#     elif 90 <= score:
#         return "优秀"
#     elif 80 <= score:
#         return "良好"
#     elif 60 <= score:
#         return "及格"
#     else:
#         return "不及格"

def get_score_level(score):
    if score < 0 or score > 100:
        return "成绩输入有误"
    if 90 <= score:
        return "优秀"
    if 80 <= score:
        return "良好"
    if 60 <= score:
        return "及格"
    return "不及格"

print(get_score_level(95))
"""
    定义函数,判断列表中是否存在相同元素
    输入:[3,4,6,8,6]
    输出:True
"""

def is_repeating(list_target):
    for r in range(len(list_target) - 1):
        for c in range(r + 1, len(list_target)):
            if list_target[r] == list_target[c]:
                return True
    return False

list01 = [3,4,6,8,7]
print(is_repeating(list01))
"""
    函数内存分配
"""

# 将函数的代码,存储到代码区,函数体中的代码不执行。
def fun01():
    a = 100

# 调用函数时,在内存中开辟空间,存储函数内部定义的变量,该空间叫做栈帧。
# 函数执行过后,栈帧释放。
fun01()

def fun02(p1,p2):
    p1 = 20
    p2[0] = 20

# 结论1:传入不可变对象,函数体内部不可能修改数据
a = 10
# 结论2:传入可变对象,函数体内部可能修改数据
b = [10]
fun02(a,b)
print(a)#?
print(b)#?20


def fun03(p1,p2):
    p1[0] = 20
    p2 = 20

a = [10]
b = [10]
fun02(a,b)
print(a)#?
print(b)#?

在这里插入图片描述
在这里插入图片描述

"""
定义方阵转置函数
for c in range(len(list01)-1):
    for r in range(c+1, len(list01)):
       list01[r][c],list01[c][r] = list01[c][r] ,list01[r][c]
"""
# def square_matrix_tranpose(matrix):
#     for c in range(len(matrix) - 1):
#         for r in range(c + 1, len(matrix)):
#             matrix[r][c], matrix[c][r] = matrix[c][r], matrix[r][c]
#     return matrix
#
# list01 = [
#     [1,2,3,4],
#     [5,6,7,8],
#     [9,10,11,12],
#     [13,14,15,16],
# ]
# print(square_matrix_tranpose(list01))

def square_matrix_tranpose(matrix):
    for c in range(len(matrix) - 1):
        for r in range(c + 1, len(matrix)):
            matrix[r][c], matrix[c][r] = matrix[c][r], matrix[r][c]

list01 = [
    [1,2,3,4],
    [5,6,7,8],
    [9,10,11,12],
    [13,14,15,16],
]

square_matrix_tranpose(list01)
print(list01)

七、变量作用域

  1. 作用域:变量起作用的范围。
  2. Local局部作用域:函数内部。
  3. Enclosing 外部嵌套作用域 :函数嵌套。
  4. Global全局作用域:模块(.py文件)内部。
  5. Builtin内置模块作用域:builtins.py文件。
1. 变量名的查找规则
  1. 由内到外:L -> E -> G -> B
  2. 在访问变量时,先查找本地变量,然后是包裹此函数外部的函数内部的变量,之后是全局变量,最后是内置变量。
2. 局部变量
  1. 定义在函数内部的变量(形参也是局部变量)
  2. 只能在函数内部使用
  3. 调用函数时才被创建,函数结束后自动销毁
3. 全局变量
  1. 定义在函数外部,模块内部的变量。
  2. 在整个模块(py文件)范围内访问(但函数内不能将其直接赋值)。
4. global 语句
  1. 作用:
    在函数内部修改全局变量。
    在函数内部定义全局变量(全局声明)。
  2. 语法:
    global 变量1, 变量2, …
  3. 说明
    在函数内直接为全局变量赋值,视为创建新的局部变量。
    不能先声明局部的变量,再用global声明为全局变量。
5. nonlocal 语句
  1. 作用:
    在内层函数修改外层嵌套函数内的变量
  2. 语法
    nonlocal 变量名1,变量名2, …
  3. 说明
    在被嵌套的内函数中进行使用
"""
    变量作用域
"""

# 全局作用域:整个.py文件
# 全局变量
g01 = 100

def fun01():
    # 局部作用域:函数的内部
    # 局部变量
    a = 10
    print(a)
    # 可以在局部作用域中,读取全局变量。
    # print(g01)

    # 实际创建了局部变量,没有改变全局变量。
    # g01 = 200

    # 声明全局变量
    global g01
    g01 = 200

    # global g02
    # g02 = 500

fun01()

print(g01)
# print(g02)

八、函数参数

1. 实参传递方式argument
1.1 位置传参
  • 定义:实参与形参的位置依次对应。
1.2 序列传参
  • 定义:实参用*将序列拆解后与形参的位置依次对应。
1.3 关键字传参
  • 定义:实参根据形参的名字进行对应。
1.4 字典关键字传参
  • 定义:实参用**将字典拆解后与形参的名字进行对应。
  • 作用:配合形参的缺省参数,可以使调用者随意传参。
2. 形参定义方式parameter
1. 缺省参数
  • 语法:
def 函数名(形参名1=默认实参1, 形参名2=默认实参2, ...):
	函数体
  • 说明:
    • 缺省参数必须自右至左依次存在,如果一个参数有缺省参数,则其右侧的所有参数都必须有缺省参数。
    • 缺省参数可以有0个或多个,甚至全部都有缺省参数。
2. 位置形参
  • 语法:
def 函数名(形参名1, 形参名2, ...):
	函数体
3. 星号元组形参
  • 语法:
def 函数名(*元组形参名):
	函数体
  • 作用:
    • 收集多余的位置传参。
  • 说明:
    • 一般命名为’args’
    • 形参列表中最多只能有一个
4. 命名关键字形参
  • 语法:
def 函数名(*, 命名关键字形参1, 命名关键字形参2, ...):
	函数体
def 函数名(*args, 命名关键字形参1, 命名关键字形参2, ...):
    函数体
  • 作用:
    • 强制实参使用关键字传参
5. 双星号字典形参
  • 语法:
def 函数名(**字典形参名):
	函数体
  • 作用:
    • 收集多余的关键字传参
  • 说明:
    • 一般命名为’kwargs’
    • 形参列表中最多只能有一个
3. 参数自左至右的顺序
  • 位置形参 --> 星号元组形参 --> 命名关键字形参 --> 双星号字典形参
"""
    函数参数
        实际参数
"""


def fun01(a, b, c):
    print(a)
    print(b)
    print(c)


# 1. 位置实参:根据位置,将实参传递给形参。
fun01(1, 2, 3)

# 2.序列实参:使用星号将序列拆分后,与形参进行对应。
list01 = [4, 5, 6]
fun01(*list01)

# 3.关键字:根据名称,将实参传递给形参。
fun01(a=1, c=3, b=2)

# 4. 字典实参:使用双星号将字典拆分后,与形参进行对应。
dict01 = {"c": 3, "b": 2, "a": 1}
fun01(**dict01)
"""
    函数参数
        实际参数
            位置实参
                序列实参
            关键字实参
                字典实参

        形式参数
            默认形参
            位置形参
                星号元组形参
            命名关键字形参
                双星号字典形参

"""


# 1. 位置形参:约束实参必须提供     【必填】
def fun01(a, b, c):
    print(a)
    print(b)
    print(c)


# 2. 默认参数:实参可以不提供      【可选】
def fun02(a=0, b="", c=0.0):
    print(a)
    print(b)
    print(c)


fun02(1)
fun02(b="bb")


# 3. 星号元组形参:将位置实参合并为一个元组
# 只能有一个,建议形参名称位args
def fun03(*args):
    print(args)


fun03(1, 2, 3)


# fun03(a = 1,b=2)

# 4. 命名关键字形参:星号元组形参,后面的位置形参,必须使用关键字实参传递。
def fun04(*args, a, b, c):
    print(args)


fun04(1, 2, 3, 4, 5, a=1, b=2, c=3)


# 命名关键字形参:星号后面的位置形参,必须使用关键字实参传递。
def fun05(a, *, b=0, c=0):
    print(a)
    print(b)
    print(c)


fun05(1, c=3)

# print(*args, sep=' ', end='\n')
print(1, 2, 3, 4, end=" ")
print(1, 2, 3, 4, sep="-")
print(1, 2, 3, 4, end=" ", sep="-")

# 5. 双星号字典形参:将关键字实参合并为一个字典
# 只能有一个,建议形参名称位args
def fun06(**kwargs):
    print(kwargs)

fun06(a = 1,b = 2)
"""
    定义函数计数器,统计函数被调用的次数。
"""

count = 0


def fun01():
    global count
    count += 1


fun01()
fun01()
fun01()
print("执行次数是:" + str(count))
"""
    定义函数,根据小时、分钟、秒计算总秒数。
    要求:
        根据小时、分钟、秒
        根据小时、分钟
        根据分钟、秒
        根据分钟
"""


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(1, 2))
print(get_total_second(minute=2, second=3))
print(get_total_second(minute=2))
"""
    定义函数,多个数值累加.
"""


def sum(*args):
    sum_value = 0
    for item in args:
        sum_value += item
    return sum_value

print(sum(213,3,4,3,5,6,67))
print(sum())

# def sum(args):
#     sum_value = 0
#     for item in args:
#         sum_value += item
#     return sum_value
#
# print(sum([213,3,4,3,5,6,67]))
# print(sum([]))
4. 强化
"""
    调用下列函数
"""


def fun01(*args, **kwargs):
    print(args)
    print(kwargs)

fun01()
fun01(12,2,a = 1,b=2)
# fun01(12,a = 1,2,b=2)


def fun02(a, *args, b, c="", **kwargs):
    print(a)
    print(args)
    print(b)
    print(c)
    print(kwargs)


fun02(1,2,3,b = 2,c="3",d = 4)
fun02(a = 1,b = 2)
"""
    对字符串:"  自强不 息,  厚德 载物. "
    查找空格数量
    删除所有空格
    查找"厚德"位置
    判断是否以"自强"开头
"""
message = "  自强不 息,  厚德 载物. "
print(message.count(" "))
print(message.replace(" ",""))
print(message.find("厚德"))
print(message.startswith("自强"))
5. 总结
  • 实际参数:调用函数
    • 位置实参:根据位置与形参对应
      • 序列实参:拆分序列后根据位置与形参对应
    • 关键字实参:根据名称与形参对应
      • 字典实参:拆分字典后根据名称与形参对应
  • 形式参数:定义函数
    • 缺省参数:实参可以不提供
    • 位置形参:实参必须提供
      • 星号元组形参:将位置实参合并为元组,位置实参数量无限
    • 命名关键字形参:约束实参必须使用关键字实参
      • 双星号字典形参:将关键字实参合并为字典,关键字实参数量无限

九、重构

  • 购物
# 重构:结构清晰,主题鲜明。
#    实现细节 --> 执行过程
# shift + F6 一键修改变量名
# ctrl+alt+m 提取函数
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 = []


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


def create_order():
    """
        创建订单
    :return: 字典类型的订单对象
    """
    while True:
        cid = int(input("请输入商品编号:"))
        if cid in dict_commodity_info:
            break
        else:
            print("该商品不存在")
    count = int(input("请输入购买数量:"))
    return {"cid": cid, "count": count}


def print_commdity_info():
    for key, value in dict_commodity_info.items():
        print("编号:%d,名称:%s,单价:%d。" % (key, value["name"], value["price"]))


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


def settlement():
    """
        结算
    """
    total_price = calculate_total_price()
    print_order_into()
    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 print_order_into():
    for order in list_order:
        dict_commodity = dict_commodity_info[order["cid"]]
        print("商品:%s,单价:%d,数量:%d." % (dict_commodity["name"], dict_commodity["price"], order["count"]))


def calculate_total_price():
    """
        计算总价
    :return: 数值类型的总价格
    """
    total_price = 0
    for order in list_order:
        dict_commodity = dict_commodity_info[order["cid"]]
        total_price += dict_commodity["price"] * order["count"]
    return total_price


shopping()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柠檬小帽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值