python_day08(笔记及练习)

这篇博客详细介绍了Python函数参数的不同类型,包括位置传参、关键字传参、字典关键字传参和缺省参数等。还讨论了形参定义方式,如星号元组形参、命名关键字形参和双星号字典形参。此外,文章涵盖了作用域的概念,如局部、外部嵌套、全局和内置作用域,并解释了变量查找规则以及如何在函数内部通过global和nonlocal语句操作全局变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数参数
实参传递方式argument

"""
    函数参数
        实际参数:调用者以何种方式传递数据
            位置实参
                -- 序列实参
            关键字实参
                -- 字典实参
"""


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


# 1. 位置实参:位置
func01(1, 2, 3)

list01 = ["a", "b", "c"]
# 2.   -- 序列实参:拆
func01(*list01)

# dict01 = {"悟空":2,"唐三藏":3,"春光灿烂猪八戒":7}
# func01(*dict01)# 之传入key,所以没有意义

# 3. 关键字实参:名字
func01(p3=2, p1=1, p2=3)

# 4.  -- 字典实参:拆
dict01 = {"p3": "c", "p1": 1, "p2": "b"}
func01(**dict01)
"""
    函数内存分配
"""

# 将函数创建的代码加载到内存中(代码区)
# 备注:函数不执行
def func01():
    a = 1000

# 调用函数在内存中开辟空间(栈帧)
# 备注:存储在函数内部创建的变量
func01()
# 函数执行后栈帧销毁


# 结论:
#  不可变类型的数据传参时,函数内部不会改变原数据的值。
#  可变类型的数据传参时,函数内部可以改变原数据。

def func02(p1,p2):
    # 修改栈帧中变量存储的地址
    p1 = 100
    # 修改列表第一个元素存储的地址
    p2[0] = 200

a = 10 # 不可变对象
b = [20] # 可变对象
# 将变量a,b存储的数据地址传入函数
func02(a,b)
print(a)# 10
print(b)# [200]
"""
    形式参数:约束实参
        默认形参:可选
        位置形参:必选
            星号元组形参:合(位置实参)
        命名关键字形参:强制使用关键字实参
            双星号字典形参:合(关键字实参)

    练习:exercise08/09
"""


# 1. 位置形参:必选
def func01(p1, p2, p3):
    print(p1)
    print(p2)
    print(p3)


# 2. 默认形参:可选
def func02(p1=True, p2="", p3=0):
    print(p1)
    print(p2)
    print(p3)


func02()
func02(False, "a", 10)
func02(p2="A")
func02(False, p3="C")


# 3. 星号元组形参: 合(位置实参)
# 备注:以args命名(不叫p1)
def func03(*p1):
    print(p1)


func03()
func03(34, 4, 5, 6, 7, 8)
list01 = [43, 54, 5, 6]
func03(*list01)  # 拆


# func03(a = 1,b = 2)

# 4. 命名关键字形参:必须使用关键字实参
#   星号后面的形参是命名关键字形参
def func04(*args, p1, p2):
    print(args)
    print(p1)
    print(p2)


func04(1, p1=2, p2=3)

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

作用域LEGB
1. 作用域:变量起作用的范围。
2. Local局部作用域:函数内部。
3. Enclosing 外部嵌套作用域 :函数嵌套。
4. Global全局作用域:模块(.py文件)内部。
5. Builtin内置模块作用域:builtins.py文件。

"""
    作用域
        局部
        全局
"""

# 全局作用域:整个文件都可以使用
g01 = "a"
def func01():
    # 局部作用域:函数内部可以使用
    a = 100
    print(g01)# 可以读取全局变量

def func02():
    # 在局部作用域创建了变量g01(没有修改全局变量)
    # g01 = "b"
    global g01 # 声明变量
    g01 = "b"
    global g02 # 特别不建议
    g02 = "c"

func01()
func02()
print(g01)# ?
print(g02)# ?


变量名的查找规则
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. 说明
在被嵌套的内函数中进行使用

# 1.
def func01(p1,p2):
    p1= ["孙悟空"]
    p2[0] = ["猪八戒"]

a = ["悟空"]
b = ["八戒"]
func01(a,b)
print(a)# ['悟空']
print(b)# [['猪八戒']]

# 2.
def func02(p1,p2):
    p2[:] = "孙悟空"
    p1[:] = p1[::-1]

a = [10,20,30]
b = ["a","b","c"]
func02(a,b)
print(a)
print(b)


"""
    改造day07/exercise04代码
    定义 矩阵转置 函数

    改造day08/day07_exercise/exercise04代码
    定义 方阵转置 函数
"""

def matrix_transpose(list_matrix):
    """
        矩阵转置
    :param list_matrix:
    :return: 新矩阵
    """
    list_result = []
    for c in range(len(list_matrix[0])):
        line = []
        for r in range(len(list_matrix)):
            line.append(list_matrix[r][c])
        list_result.append(line)
    return list_result

# 测试
list01 = [
    [1,2,3,4],
    [5,6,7,8],
    [9,10,11,12],
]
print(matrix_transpose(list01))

def square_matrix_transpose(square_matrix):
    for c in range(len(square_matrix) - 1):
        for r in range(c + 1, len(square_matrix)):
            # 3. 修改可变对象
            square_matrix[r][c], square_matrix[c][r] = square_matrix[c][r], square_matrix[r][c]
    # 3. 无需通过 return 返回结果
    # return square_matrix

# 测试
list01 = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
    [9, 10, 11, 12],
]
# 1. 传入可变对象
# print(square_matrix_transpose(list01))
square_matrix_transpose(list01)

print(list01)
"""
    改造day07/exercise07代码
    定义 删除列表中相同元素 函数

    体会:传入可变对象、修改可变对象、无需返回值
"""


def delete_duplicates(list_target):
    """

    :param list_target:
    :return:
    """
    count = 0
    for r in range(len(list_target) - 1, -1, -1):
        for c in range(r):
            if list_target[r] == list_target[c]:
                del list_target[r]
                count += 1
                break
    return count

# 测试
list01 = [34, 8, 56, 9, 8, 9]
print(delete_duplicates(list01))
print(list01)
"""
    改造day07/exercise05代码
    定义 排序 函数
    体会:传入可变对象、修改可变对象、无需返回值 
"""

def sort(list_target):
    """

    :param list_target:
    :return:
    """
    for r in range(len(list_target) - 1):  # 0       1
        for c in range(r + 1, len(list_target)):  # 123..   234..
            if list_target[r] > list_target[c]:
                list_target[r], list_target[c] = list_target[c], list_target[r]

list01 = [4, 54, 5, 6, 7, 8, 3]
sort(list01)
print(list01)
"""
    改造day03/exercise05代码
    定义 根据月份计算天数的 函数
"""


def is_leap_year(year):
    """
        判断是否为闰年
    :param year:
    :return:
    """
    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0


def get_day_by_month(year, month):
    """
        获取天
    :param year:
    :param month:
    :return:
    """
    if month < 1 or month > 12:
        return 0
    if month == 2:
        return 29 if is_leap_year(year) else 28
    if month == 4 or month == 6 or month == 9 or month == 11:
        return 30
    return 31
# 练习: 质数:大于1的整数,除了1和自身以外,不能被其他数字整除
#     定义函数,获取指定范围内的所有质数.
#     例如:2 ~ 20
#      [2,3,5,7,11,13,17,19]

# def get_primes(begin, end):
#     list_result = []
#     for number in range(begin, end + 1):  # 7
#         for item in range(2, number):  # 2 3 ...6
#             if number % item == 0:  # 7  % 2
#                 # 不是质数
#                 break
#         else:
#             # 是质数
#             list_result.append(number)
#     return list_result

def is_prime(number):
    for item in range(2, number):
        if number % item == 0:  # 7  % 2
            return False
    return True

def get_primes(begin, end):
    # list_result = []
    # for number in range(begin, end + 1):
    #     if is_prime(number):
    #         list_result.append(number)
    # return list_result
    return [number for number in range(begin, end + 1) if is_prime(number)]

# 测试
print(get_primes(2, 20))
# 练习:定义函数,根据时,分,秒,计算总秒数.
# 测试:
#   时,分,秒 --> 总秒数
#   时,分 --> 总秒数
#   分 --> 总秒数
#   时,秒--> 总秒数
def get_total_second(hour=0, minute=0, second=0):
    return hour * 3600 + minute * 60 + second


# 1时,2分,3秒 --> 总秒数
print(get_total_second(1, 2, 3))
# 1时,2分 --> 总秒数
print(get_total_second(1, 2))
# 2分 --> 总秒数
print(get_total_second(minute=2))
# 1时,3秒--> 总秒数
print(get_total_second(1,second=3))
# 练习:定义函数,数值相加的函数.
# 测试:1,2
#      1,2,5,54,65,6,
def sum_numbers(*args):
    # sum_value = 0
    # for item in args:
    #      sum_value += item
    # return sum_value
    return sum(args)

print(sum_numbers())
print(sum_numbers(1, 2, 3, 54, 4, 56, 6, 7))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值