# 函数

# 一、返回多个值

'''
函数高级: 返回多个值.

需求: 模拟计算器, 即: 定义一个函数 calc(), 用来获取两个整数的 加减乘除结果, 并返回.

细节:
    Python中的函数如果返回多个值, 默认是把这个多个值放到一个元组中, 然后返回的.
'''


# 1. 定义函数. 3个明确, 函数名:calc  参数列表:a,b  返回值: 加减乘除结果
def calc(a, b):  # 形参
    '''
    模拟计算器, 求两个整数的加减乘除结果.
    :param a: 要计算的第1个整数
    :param b: 要计算的第2个整数
    :return: 分别对应加减乘除结果.
    '''
    sum = a + b
    sub = a - b
    mul = a * b
    div = a // b  # //整除,   /除法
    return sum, sub, mul, div


# 2. 调用函数. 3个步骤, 写函数名, 传参, 接收返回值.
result = calc(10, 3)  # 实参       (13, 7, 30, 3), tuple 元组 
print(result, type(result))

print(f'求和结果为 {result[0]}, 差为 {result[1]}, 积为 {result[2]}, 商为 {result[3]}')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 二、位置参数和关键词参数

'''
函数的参数问题详解之 位置参数
    结论:
        位置参数的个数以及顺序必须和形参的个数及顺序保持一致.
'''


# 定义函数. 3个明确.
def show(name, age, address):
    print(f'我叫 {name}, 年龄是 {age}, 老家是 {address}')


# 调用函数.   3个步骤.
# show('刘亦菲', 33)   # 报错, 位置参数的个数以及顺序必须和形参的个数及顺序保持一致

# 位置参数
show('刘亦菲', 33, '北京')

# 如果用位置参数, 有可能会因为用户手误导致参数顺序问题, 从而和我们预期结果不一致.
show('刘亦菲', '北京', 33)

# 针对于上述的问题, 我们可以用 关键字参数解决.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
'''
函数的参数问题详解之 关键字参数
    格式:
        在传参的时候, 通过 形参名 = 值 的方式, 可以把值传给具体的形参.
    细节:
        1. 如果实参全都是关键字参数, 则顺序无要求, 随便写, 个数得保持一致.
        2. 如果是位置参数, 则个数和位置都要保持一致.
        3. 如果是混合参数(既有位置参数, 又有关键字参数), 则必须 位置参数在前, 关键字参数在后.
'''


# 定义函数. 3个明确.
def show(name, age, address):
    print(f'我叫 {name}, 年龄是 {age}, 老家是 {address}')


# 如果用位置参数, 有可能会因为用户手误导致参数顺序问题, 从而和我们预期结果不一致.
show('刘亦菲', '北京', 33)
print('-' * 31)

# 采用 关键字参数
show(address='上海', name='高圆圆', age=35)
print('-' * 31)

# 采用 混合参数(位置参数 + 关键字参数)
# show(address='上海', name='高圆圆', 35)   # 报错, 位置参数在前,关键字参数在后.
show('力宏', address='中国台湾', age=29)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 三、缺省参数

'''
函数的参数问题详解之 缺省参数
    格式:
        在定义函数的时候, 直接通过 形参名=值 的方式给该形参一个默认值.
    细节:
        如果方法有缺省参数, 则在调用方法的时候, 可以考虑不给该参数传值, 如果不传, 就用默认值.
        如果传了, 就用你传入的值.
'''


# 定义函数. 3个明确.
#                    缺省参数
def show(name, age, address='中国'):
    print(f'我叫 {name}, 年龄是 {age}, 老家是 {address}')


# 如果不给 缺省参数传参, 则用 缺省值(缺省参数的默认值)
show('乔峰', 33)

# 给缺省参数赋值.
show('虚竹', 29, '大宋')

# 混合调用.
#   位置参数      关键字参数
show('段誉', address='大理', age=18)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 四、可变参数

'''
函数的参数问题详解之 不定长参数
    概述:
        不定长参数也叫可变参数, 即: 参数的个数是可变的.
    格式:
        在形参名的前边写上 *, 或者 **,
        如果是 * 则表示可以接收所有的 位置参数, 形成元组.
        如果是 ** 则表示可以接收所有的 关键字参数, 形成字典.
    细节:
        1. 如果位置参数, 一般用 *args表示.
        2. 如果是关键字参数, 一般用 **kwargs       kw: keyword 关键字的意思.
        3. 可变参数用于形参, 表示可以接收任意个实参, 最少0个, 最多无数个.
'''


# 需求1: 演示可变参数之 位置参数.
# 需求: 定义函数, 求和.
# 分解版
def getSum3(a, b, c):
    return a + b + c


def getSum4(a, b, c, d):
    return a + b + c + d


# 我们发现, 上述的代码, 形参列表是不同的, 但是函数体是高度相似的, 我们可以用 可变参数(不定长参数)优化, 如下.
def getSum(*args):  # 你把这的 args当做元组即可.
    print(args, type(args))     # tuple 元组类型.
    # 定义求和变量.
    sum = 0
    # 遍历, 获取每个数字, 然后累加.
    for i in args:
        sum += i
    return sum  # 返回求和结果


# 调用getSum()函数
print(getSum())
print(getSum(10, 20))
print(getSum(10, 20, 30))
print(getSum(33, 11, 5, 66))
# print(getSum(33, 11, 5, 66, age=33))    #报错,  *args 可变参数, 能接受所有的位置参数, 形成元素, 无法接收 关键字参数.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
'''
函数的参数问题详解之 不定长参数
    概述:
        不定长参数也叫可变参数, 即: 参数的个数是可变的.
    格式:
        在形参名的前边写上 *, 或者 **,
        如果是 * 则表示可以接收所有的 位置参数, 形成元组.
        如果是 ** 则表示可以接收所有的 关键字参数, 形成字典.
    细节:
        1. 如果位置参数, 一般用 *args表示.
        2. 如果是关键字参数, 一般用 **kwargs       kw: keyword 关键字的意思.
        3. 可变参数用于形参, 表示可以接收任意个实参, 最少0个, 最多无数个.
        4. *args是位置参数的, **kwargs是接收关键字参数, 不冲突, 所以在一个函数中, 可以共存.
'''


# 定义函数.
def show(**kwargs):  # 它只能接收 关键字参数, 形成字典.
    print(type(kwargs))  # <class 'dict'>
    print(kwargs)


# 调用函数.
# show(10, 20, 30)    # 报错, **kwargs, 只能接收 关键字参数.

show(name='刘亦菲', age=33)
print('-' * 31)


# 演示: 函数能不能既有 *args, 又有 **kwargs呢?
def func1(*args, **kwargs):
    print(args, type(args))  # (10, 20, 30) <class 'tuple'>
    print(kwargs, type(kwargs))  # {'name': '高圆圆', 'age': 35} <class 'dict'>


# 调用函数
#      位置参数      关键字参数
func1(10, 20, 30, name='高圆圆', age=35)
print('-' * 31)


#           普通参数    可变参数    缺省参数
def func2(name, age,    *args,      address='中国'):
    print(name, age, address, args)


#     位置参数              关键字参数
func2(10, 20, 30, 40, 50, address='北京')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

# 五、参数传递问题

'''
Python中的 参数传递 问题:
    概述:
        如果在不改变引用的情况下, 能修改内容, 则该类型就是: 可变类型.
        如果在不改变引用的情况下, 不能修改内容, 则该类型就是: 不可变类型.

    结论(细节, 要求记忆):
        1. 在Python中, 所有的传递, 传递的都是: 地址值.
        2. 如果形参是可变类型, 则形参的改变直接影响实参.
        3. 如果形参是不可变类型, 则形参的改变对实参没有任何影响.
        4. Python中的类型, 按照可变类型和不可变类型具体划分如下:
            可变类型: list, dict
            不可变类型: int, float, str, bool, tuple
'''

# 演示: 如果形参是不可变类型, 则形参的改变对实参没有任何影响.
# 1. 定义变量.
a = 10
# 2. 打印变量.
print(f'函数调用前, a = {a}') # 10
# 3. 定义函数, 并且修改 上述变量(类型)的值.
def show(a):    # int, 形参, 不可变类型
    a = 200

# 4. 调用函数.
show(a)  # 实参

# 5. 重新打印变量.
print(f'函数调用后, a = {a}') # 10
print('-' * 13)

# 演示: 如果形参是可变类型, 则形参的改变直接影响实参.
# 1. 定义变量.
list1 = ['aa', 'bb', 'cc']
# 2. 打印变量.
print(f'函数调用前, list1 = {list1}') #
# 3. 定义函数, 并且修改 上述变量(类型)的值.
def func(list1):    # int, 形参, 不可变类型
    list1[1] = 'ff'

# 4. 调用函数.
func(list1)  # 实参

# 5. 重新打印变量.
print(f'函数调用后, list1 = {list1}')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

# 六、匿名函数

'''
匿名函数解释:
    概述:
        所谓的匿名函数指的就是Python中的Lambda表达式, 用来简化函数写法的.
    作用:
        1. 简化Python函数写法.
        2. 让我们的代码更加灵活.
        3. 匿名函数可以作为参数传递.
    格式:
        普通函数的格式:
            def 函数名(形参列表):
                函数体
                return 具体的返回值
        匿名函数格式:
            lambda 形参列表 : [return] 结果
            上述格式的变形版:
                变量名 = lambda 形参列表 : [return] 结果   # 这里的变量名, 其实可以理解为: 函数名
'''


# 1. 演示无参的匿名函数.
def show1():
    return 10
print(show1())

# 上述代码用 匿名函数优化后为
# print(lambda: 10)  # 打印引用.

func1 = lambda: 10  # lambda : 10 表示匿名函数, 然后将其赋值给变量 func1, 所以func1其实也是函数.
print(func1())
print('-' * 13)

# 2. 演示有参的匿名函数
def getSum(a, b):
    return a + b
print(getSum(10, 20))

# 上述代码用 匿名函数优化后为
func2 = lambda a, b : a + b
print(func2(11, 22))
print('-' * 13)

# 3. 演示有if的的匿名函数
def show3(a):
    if a % 2 == 0:
        return '偶数'
    else:
        return '奇数'
print(show3(10))

func3 = lambda a : '偶数' if a % 2 == 0 else '奇数'
print(func3(20))
print('-' * 13)


# 4. 匿名函数当做方法的实参传递.
# 需求: 定义4个方法, 分别计算两个整数的加减乘除结果, 并返回.
def method1(a, b):
    return a + b
def method2(a, b):
    return a - b
def method3(a, b):
    return a * b
def method4(a, b):
    return a / b

# 如果用匿名函数, 则上述的代码可以简化为:
def calc(a, b, lambda1):
    '''
    该函数是用来模拟计算器的, 目的是: 为了演示 匿名函数用法, 也为了说明匿名函数可以作为方法的实参进行传递.
    :param a: 要计算的第1个整数
    :param b: 要计算的第2个整数
    :param lambda1: 两个整数具体要进行的逻辑
    :return: 最终结果.
    '''
    func = lambda1   # 把lambda表达式(匿名函数) 赋值给 变量 func, 此时 func就相当于一个函数
    return func(a, b)

#        参数1 参数2  参数3: 匿名函数
print(calc(10, 3, lambda a, b : a + b))  # 实参
print(calc(10, 3, lambda a, b : a - b))
print(calc(10, 3, lambda a, b : a * b))
print(calc(10, 3, lambda a, b : a // b))

# 求最小值
print(calc(10, 3, lambda a, b : a if a < b else b))
# 求最大值
print(calc(10, 3, lambda a, b : a if a > b else b))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

# 七、魔法函数

双下划线开始和结尾的就是魔法函数

# 7.1 迭代

class Company(object):
    def __init__(self, employee_list):
        self.employee = employee_list

    def __getitem__(self, item):
        return self.employee[item]

    def __len__(self):
        return len(self.employee)

company = Company(["tom", "bob", "jane"])

for em in company:
    print(em)
    
print(len(company))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 7.2 字符串

    # 字符串表示 print(company)
    def __str__(self):
        return ",".join(self.employee)
    # 字符串表示 company.__repr__()
    def __repr__(self):
        return ",".join(self.employee)
1
2
3
4
5
6

# 7.3 数学运算

class MyVector(object):
    def __init__(self,x,y):
        self.x=x
        self.y=y
    def __add__(self, other_instance):
        re_vector = MyVector(self.x+other_instance.x,self.y+other_instance.y)
        return re_vector
    def __str__(self):
        return "x:{x},y:{y}".format(x=self.x,y=self.y)
first_vec = MyVector(1,2)
second_vec = MyVector(2,3)
print(first_vec+second_vec)
1
2
3
4
5
6
7
8
9
10
11
12
更新时间: 2/23/2023, 3:19:23 PM