python中函数可以作为容器对象_012.Python之函数的参数与对象

一、函数的参数

(一)函数参数的两大分类:

1.形参:

在定义函数阶段,括号内指定的参数,称之为形式参数,简称形参。形参相当于定义在函数内的变量名,用于接收外部传进来的值。

2.实参:

在调用函数阶段,括号内传入的值,称之为实际参数,简称实参,实参相当于变量值,用于为形参赋值的。

3.总结:

在函数调用时,会将实参的值绑定给形参,这种绑定关系只能在函数内使用,在函数调用完毕后,实参会与形参解除绑定,回收占用的内存空间。

(二)函数参数的特点及具体使用

1.位置形参

(1)按照从左到右的顺序依次定义形参

(2)特点:必须被传值,不可多,也不可少

def func(x, y):

print(x, y)

func(1, 2) # 1 2

func(1) # TypeError: func() missing 1 required positional argument: ‘y‘

2.位置实参

(1)按照从左到右的顺序依次定义实参

(2)特点:按照位置与形参一一对应

def func(x, y):

print(x, y)

func(1, 2) # 1 2

func(2, 1) # 2 1

3.关键字实参

(1)按照key=value的形式为指定的形参传值

(2)特点:指名道姓为某个形参传值,可以完全打乱顺序

def func(x, y):

print(x, y)

func(1, 2) # 1 2

func(y=2, x=1) # 1 2

(3)注意:位置实参与关键字实参的混用

①不能对同一个形参重复赋值

def func(x, y):

print(x, y)

func(1, 2, x=111) # TypeError: func() got multiple values for argument ‘x‘

②关键字实参必须跟在位置实参后面

def func(x, y):

print(x, y)

# func(1, y=2) # 1 2 操作正确,无问题

func(y=2, 1) # SyntaxError: positional argument follows keyword argument

4.默认参数

(1)具有默认值的形参,指的是在定义函数阶段就已经为参数赋值

(2)特点:在调用函数阶段可以不用为默认参数赋值

def func(x, y=1111):

print(x, y)

func(1) # 1 1111

func(1,2222) # 1 2222

(3)注意:

①位置形参必须放在默认形参的前面

def func(y=1, x):

print(x, y)

func(2) # SyntaxError: non-default argument follows default argument

②默认形参的值

默认形参的值是在函数定义阶段就被固定的,如果调用没有为默认形参传值,那么不会每次调用都重新赋值,函数的调用彼此之间应该做到没有关联,所以说默认形参的值通常应该是不可变类型。

def func(name, names=[]):

names.append(name)

print(names)

func("name1") # [‘name1‘]

func("name2") # [‘name1‘, ‘name2‘]

func("name3") # [‘name1‘, ‘name2‘, ‘name3‘]

解决办法:

def func(name, names=None):

if names == None:

names = []

names.append(name)

print(names)

func("name1") # [‘name1‘]

func("name2") # [‘name2‘]

func("name3") # [‘name3‘]

5.可变长度的参数(*与**的用法)

可变长指的是在调用函数时,传入的实参个数不固定,而实参是为形参赋值的,所以对应着也应该有新的形参格式来负责接收不固定长度的实参。

(1)形参中带*与**

1)*形参名:

“ * ”会负责把溢出的位置实参存成元组,然后赋值给后面的形参名,形参名通常应该是args。

def func(x,y,*z):

print(x,y,z)

func(1,2,3) # 1 2 (3,)

func(1,2,3,4) # 1 2 (3, 4)

func() # 报错,TypeError: func() missing 2 required positional arguments: ‘x‘ and ‘y‘

2)* * 形参名:

“* *“会负责把溢出的关键字实参存成字典,然后赋值给后面的形参名,形参名通常应该是kwargs.

def func(x,y,**z):

print(x,y,z)

func(1,2,a=111,b=222,c=333) # 1 2 {‘a‘: 111, ‘b‘: 222, ‘c‘: 333}

3)注意:*与**在形参中混用,整体规则如下:

def func(x,y=2,*m,**n):

print(x,y,m,n)

func(1) # 1 2 () {}

func(1,2,3,4,5,6,7,a=1,b=2) # 1 2 (3, 4, 5, 6, 7) {‘a‘: 1, ‘b‘: 2}

def func(*args, **kwargs):

print(args, kwargs)

func(1,2,3,4,5,6,7,a=1,b=2) # (1, 2, 3, 4, 5, 6, 7) {‘a‘: 1, ‘b‘: 2}

# 使用*args实现一个加法运算的函数

def add(*args):

res = 0

for i in args:

res += i

print(res)

add(1,2,3,4,5) # 15

(2)实参中带*与**

def func(x, y):

print(x, y)

1)实参中带*:

*后跟的那个值应该是一个可以被for循环遍历的值, * 后的那个值会被分解成位置实参。

func(*(111,222,333)) # func(111,222,333) TypeError: func() takes 2 positional arguments but 3 were given

func(*(111,222)) # 111 222 func(111,222)

func(*"hello") # func("h","e","l","l","o") TypeError: func() takes 2 positional arguments but 5 were given

func(*{"k1": 111, "k2": 222,}) # k1 k2 func("k1","k2")

2)实参中带**:

“* *“后跟的那个值应该是一个字典,**后面的那个值会被分解成关键字参数。

func(**{"k1": 111, "k2": 222, }) # func(k2=222,k1=111) TypeError: func() got an unexpected keyword argument ‘k1‘

func(**{"x": 111, "y": 222, }) # 111 222 func(y=222,x=111)

func(**[("x",111),("y",222)]) # TypeError: func() argument after ** must be a mapping, not list

(3)形参与实参中混用*与**

def func(*args,**kwargs):

print(args,kwargs)

func(1,2,3,4,5,a=1,b=2,c=3) # (1, 2, 3, 4, 5) {‘a‘: 1, ‘b‘: 2, ‘c‘: 3}

func((1, 2, 3, 4, 5), {‘a‘: 1, ‘b‘: 2, ‘c‘: 3}) # ((1, 2, 3, 4, 5), {‘a‘: 1, ‘b‘: 2, ‘c‘: 3}) {}

func(*(1, 2, 3, 4, 5), **{‘a‘: 1, ‘b‘: 2, ‘c‘: 3}) # func(1, 2, 3, 4, 5, a=1, b=2, c=3) (1, 2, 3, 4, 5) {‘a‘: 1, ‘b‘: 2, ‘c‘: 3}

示例:

def index(x,y):

print(x,y)

def wrapper(*args,**kwargs):

index(*args,**kwargs)

# 直接调用的是wrapper,然后通过wrapper间接调用index

wrapper(1,2,3,4,5,a=1,b=2,c=3) # TypeError: index() got an unexpected keyword argument ‘a‘

#① args=(1,2,3,4,5) kwargs={"a":1,"b":2,"c":3}

#② index(*(1,2,3,4,5),**{"a":1,"b":2,"c":3})

#③ index(1,2,3,4,5,a=1,b=2,c=3) # TypeError: index() got an unexpected keyword argument ‘a‘

wrapper(1,2) # 1 2

wrapper(y=2,x=1) # 1 2

wrapper(1,y=2) # 1 2

(4)总结:

形参中带*与** 是汇总操作

实参中带*与** 是分解操作

6.命名关键字参数(了解)

在*与** 之间的参数,都是命名关键字参数。

def func(*args, y, **kwargs):

print(args)

print(y)

print(kwargs)

# func(1,2,3,a=1,b=2,c=3) # 报错,不可以这样传值,必须给y赋值

func(1,2,y=3,a=1,b=2,c=3)

# (1, 2)

# 3

# {‘a‘: 1, ‘b‘: 2, ‘c‘: 3}

def func(*args, x=1, y, **kwargs):

print(args)

print(x,y)

print(kwargs)

func(1,2,y=3)

# (1, 2)

# 1 3

# {}

7.组合使用的顺序(了解)

def func(x, y=111, *args, z, **kwargs):

pass

二、函数对象

函数对象指的是函数可以被当做“数据”来处理,具体可以分为四个方面的使用:

(一)函数可以被引用(赋值)

def foo():

print(‘from foo‘)

print(foo) #

f=foo

f() # from foo

(二)函数可以作为容器类型的元素

def foo():

print(‘from foo‘)

l=[foo]

print(l) # []

l[0]() # from foo

(三)函数可以作为参数传入另一个函数

def func(aaa): # aaa=函数foo的内存地址,被引用(赋值)

print(aaa)

# aaa()

def foo():

print(‘from foo‘)

func(foo) #

(四)函数的返回值可以是一个函数

def func(aaa): # aaa=函数foo的内存地址

return aaa # 返回的是函数foo的内存地址

def foo():

print(‘from foo‘)

res=func(foo)

print(res) #

res() # from foo

示范:

def login():

print(‘登录功能‘)

def register():

print(‘注册功能‘)

def transfer():

print(‘转账功能‘)

def charge():

print(‘充值‘)

def withdraw():

print(‘提现‘)

func = {

"1": ("登录",login),

"2": ("注册",register),

"3": ("转账",transfer),

"4": ("充值",charge),

"5": ("提现",withdraw)

}

while True:

print("0 退出")

for k,v in func.items():

print(k,v[0])

choice = input("请输入你的操作编号:").strip()

if choice == "0":

break

if choice in func:

func[choice][1]()

else:

print("输入的指令不存在")

原文:https://www.cnblogs.com/huluhuluwa/p/13149910.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值