形参与实参
'''
def fn(形参们):
pass
fn(实参们)
'''
# 形参:定义函数,在括号内声明的变量名,用来结束外界传来的值
# 实参:调用函数,在括号内传入的实际值,值可以为常量、变量、表达式或三者的组合
# ***** 在函数定义()中出现的参数:形参
# ***** 形参就是拷贝实参的值,随着函数的调用才产生,随着函数调用结束而销毁
def fn(a, b, c):
# a,b,c必须要从外界获取值,采用意义
print(a)
print(b)
print(c)
# 外部提前产生了的变量,内部可以使用
print(x)
print(y)
print(z)
# x,y,z是实际存在的值
x = 10
y = 20
z = 30
# ***** 在函数调用()中出现的参数(外界实际存在的值):实参
fn(10, 20, 30)
fn(x, y, z)
fn(x + 10, y * 2, z / 5)
# ***** 调用函数是,实参可以由 常量、变量、表达式或三种的组合
# 在函数的外部不能直接使用函数的形参,原因:函数调用完毕后,形参被销毁了
print(a)
print(b)
print(c)
# 注:形参随着函数的调用而产生,随着调用结束而销毁(有特例)
实参分类
# 位置实参:必须按照顺序给形参传值
# 关键字实参:按照关键字给形参传值,所以顺序可以颠倒
# 实参作用:为形参传递值
def fn1(a, b, c):
print(a, b, c)
# 位置实参:必须按照顺序
fn1(10, 20, 30)
fn1(30, 20, 10)
# 关键字实参:可以不按顺序传递, 形参按名字取值
fn1(a=10, b=20, c=30)
fn1(c=30, b=20, a=10)
# 两者混用: 关键字实参必须出现在位置实参之后
# fn1(10, c=20, a=30) # 10按位置传参给a,a=30给a传参,c可以拿到20,但b没人传参
# TypeError:fn1() got multiple values for argument 'a' a被多次传值
# 合法传参 *****
fn1(10, c=30, b=20)
fn1(10, b=30, c=20)
def fn2(a, b, c, d, e, f):
print(a, b, c, d, e, f)
fn2(10, 20, 30, e=100, f=500, d=200)
# 注:位置实参、关键字实参共存是,关键字实参必须出现在所有位置实参之后
形参的分类
'''
位置形参:位置实参与关键字实参都可以对其传参
默认形参:位置实参与关键字实参都可以对其传参,也可以不被传参
可变长位置形参:接收位置形参、默认形参没有接收完的所有位置实参
无初值关键字形参:只能由关键字实参传值
有初值关键字形参:只能由关键字实参传值,也可以不被传值
可变长关键字参数:接收两种关键字形参没有接收完的所有关键字实参
注:各种形参出现的先后
位置形参 - 默认形参 - 可变长位置形参 - 无|有初值关键字形参 - 可变长关键字参数
'''
def fn(a, b, c=10, *args, d, e=20, f, **kwargs):
pass
# 位置形参:a、b
# 默认形参:c
# 可变长位置形参:args
# 无初值关键字形参:d、f
# 有初值关键字形参:e
# 可变长关键字参数:kwargs
# 位置形参 positional argument
def fn(a, b, c):
print(a, b, c)
# 位置形参可以由 位置实参 与 关键字实参 来传值
fn(10, 20, 30)
fn(a=10, b=20, c=30)
# 默认形参具有默认值,用=进行复制
def fn(a=10,b=20):
print(a, b)
# 默认形参可以由 位置实参 与 关键字实参 来传值,还可以不用传值(采用自身默认值)
fn(20, 30)
fn(a=200, b=300)
fn(100)
fn(b=100)
# 位置形参与默认形参同时存在,默认形参必须在后
def fn1(a,b,c=10,d=20):
print(a, b, c, d)
# 位置形参必须传值,默认形参分情况传值
fn1(100, 200, d=1000)
# 可变长形参只能由 位置实参 来传值
def fn(a, b=10, *args):
print(a, b)
print(args)
# 可变长形参会以元组形式接受 位置形参与默认形参未接受完的 所有传入的位置实参
# 小细节:可变长形参只能接受位置实参的值,位置实参还必须在关键字实参前,
# 导致默认形参只能由位置实参来传值
fn(1, 20, 100, 200)
fn(100)
# 可变长位置形参整体赋值
def fn(*args):
print(args)
fn(1, 2, 3, 4, 5) # (1, 2, 3, 4, 5)
a = 'ab'
b = [1, 2]
c = (1, 2)
d = {1, 2}
fn(a) # ('ab', )
fn(b) # ([1, 2], )
fn(c) # ((1, 2), )
fn(d) # ({1, 2}, )
# 问
# 就拿a,b,c,d进行传值,如何得到
'''
('a', 'b')
(1, 2)
'''
# *单列集合(保护字符串)将该变量进行 打散 传值 (本质传递的是地址)
fn(*a)
fn(*b)
fn(*c)
fn(*d)
# 打散
def fn1(*args):
print(args)
ls = [1, 2, 3, 4, 5]
fn1(ls) # (ls, )
fn1(*ls) # 将ls打散为1,2,3,4,5再进行传值=>(1,2,3,4,5)
# 关键字形参
# *为分割线,可以有变量名 *args, 也可以只用来做分隔
# a:位置
# b:默认
# c,e:无值关键字形参
# d:有值关键字形参
# 注:
# a和b有先后顺序
# c,d, e无先后顺序
# *****关键字形参必须由 关键字实参 来传值, 出现在*后的都是关键字形参
def tt(a, b=10, *, c, d=10, e):
print(a, b, c, d, e)
# keyword-only arguments
def fn(*, a, b=10, c):
print(a, b, c)
# fn(10, 20, 30) # 错误:TypeError: fn() takes 0 positional arguments but 3 were given
fn(b=300, c=100, a=200)
# 可变长关键字形参
# 可变长关键字形参:用来接收没有被关键字形参接收完的关键字形参,也只能由关键字实参来传值
# 用字典来存放数据
def fn(*, a, b=20, c, **kwargs):
print(a, b)
print(kwargs)
fn(d=40, e=50, a=10, c=30)
# 整体赋值
dic = {'name': 'Owen', 'age': 18}
def fn1(**kwargs):
print(kwargs)
fn1(**dic)
dd = {
'k1': [1, 2, 3, 4, 5],
'k2': {"name":"Bob"}
}
fn1(**dd)
def fn2(*args):
print(args)
ll = [1, [1, 2], {"name":"Bob"}]
fn2(*ll) # (1, [1, 2], {"name":"Bob"})
# 参数总结
def fn(a, b=10, *args, d, f=20, **kwargs):
print(a)
print(b)
print(args)
print(d)
print(f)
print(kwargs)
# 有位置实参传值: args和kwargs如果都能接收到值:
# b必须传值且只能用位置实参传值,f可以不用传值
fn(1,2,3,4,d=5,g=6,k=7)
print()
# 全部用关键字实参传值
fn(x=100,y=200,d=300,b=400,a=500)
# 1.位置形参与默认形参: 能用 位置实参 关键字实参 传值
# 2.可变长位置形参:只能 位置实参 传值
# 3.所以关键字形参:只能 关键字实参 传值
可变参数的整体使用
# 1、可变位置形参以元组方式接收值
# 如:接收10,20,30三个数
def fn1(*args):
print(args) # (10, 20, 30)
# 第一种传参
fn1(10, 20, 30)
# 第二种传参
t = (10, 20, 30) # 单列集合及字符串类型都可以
fn1(*t)
# 2、可变位置实参以字典方式接收值
def fn2(**kwargs):
print(kwargs) # {'name': 'Owen', 'age': 18}
# 第一种传参
fn2(name='Owen', age=18)
# 第二种传参
d = {'name': 'Owen', 'age': 18} # 单列集合及字符串类型都可以
fn2(**d)