函数
函数
一、返回多个值
'''
函数高级: 返回多个值.
需求: 模拟计算器, 即: 定义一个函数 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]}')
二、位置参数和关键词参数
'''
函数的参数问题详解之 位置参数
结论:
位置参数的个数以及顺序必须和形参的个数及顺序保持一致.
'''
# 定义函数. 3个明确.
def show(name, age, address):
print(f'我叫 {name}, 年龄是 {age}, 老家是 {address}')
# 调用函数. 3个步骤.
# show('刘亦菲', 33) # 报错, 位置参数的个数以及顺序必须和形参的个数及顺序保持一致
# 位置参数
show('刘亦菲', 33, '北京')
# 如果用位置参数, 有可能会因为用户手误导致参数顺序问题, 从而和我们预期结果不一致.
show('刘亦菲', '北京', 33)
# 针对于上述的问题, 我们可以用 关键字参数解决.
'''
函数的参数问题详解之 关键字参数
格式:
在传参的时候, 通过 形参名 = 值 的方式, 可以把值传给具体的形参.
细节:
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)
三、缺省参数
'''
函数的参数问题详解之 缺省参数
格式:
在定义函数的时候, 直接通过 形参名=值 的方式给该形参一个默认值.
细节:
如果方法有缺省参数, 则在调用方法的时候, 可以考虑不给该参数传值, 如果不传, 就用默认值.
如果传了, 就用你传入的值.
'''
# 定义函数. 3个明确.
# 缺省参数
def show(name, age, address='中国'):
print(f'我叫 {name}, 年龄是 {age}, 老家是 {address}')
# 如果不给 缺省参数传参, 则用 缺省值(缺省参数的默认值)
show('乔峰', 33)
# 给缺省参数赋值.
show('虚竹', 29, '大宋')
# 混合调用.
# 位置参数 关键字参数
show('段誉', address='大理', age=18)
四、可变参数
'''
函数的参数问题详解之 不定长参数
概述:
不定长参数也叫可变参数, 即: 参数的个数是可变的.
格式:
在形参名的前边写上 *, 或者 **,
如果是 * 则表示可以接收所有的 位置参数, 形成元组.
如果是 ** 则表示可以接收所有的 关键字参数, 形成字典.
细节:
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. 如果位置参数, 一般用 *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='北京')
五、参数传递问题
'''
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}')
六、匿名函数
'''
匿名函数解释:
概述:
所谓的匿名函数指的就是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))
七、魔法函数
双下划线开始和结尾的就是魔法函数
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))
7.2 字符串
# 字符串表示 print(company)
def __str__(self):
return ",".join(self.employee)
# 字符串表示 company.__repr__()
def __repr__(self):
return ",".join(self.employee)
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)