Python学习笔记15

chapter_15

参数


传递参数

  • 不可变对象参数通过值传递
  • 可变对象是通过”指针”进行传递的
>>> def changer(a,b):
...   a = 2
...   b[0] = 'spam'
... 
>>> X = 1
>>> L = [1,2]
>>> changer(X,L) 
>>> X,L  #X的值没有改变,L的值被改变了
(1, ['spam', 2])
  • 原因:
>>> X = 1
>>> a = X
>>> a = 2
>>> print(X)
1


>>> L = [1,2]
>>> b = L
>>> b[0] = 'spam'
>>> print(L)
['spam', 2]

避免对可变对象作为参数的修改

  • 在调用时对可变对象进行拷贝
>>> def changer(a,b):
...   a = 2
...   b[0] = 'spam'
... 
>>> X = 1
>>> L = [1,2]
>>> changer(X,L[:]) #在调用时对列表进行拷贝 
  • 在函数内部进行拷贝
>>> def changer(a,b):
...   b = b[:]  #在对对象进行操作前进行拷贝
...   a = 2
...   b[0] = 'spam'
... 
>>> X = 1
>>> L = [1,2]
>>> changer(X,L) 
  • 将可变对象转变为不可变对象
>>> def changer(a,b):
...   a = 2
...   b[0] = 'spam'
... 
>>> X = 1
>>> L = [1,2]
>>> changer(X,tuple(L)) #在调用时将列表转为元组 

参数匹配语法

func(value)常规参数:通过位置进行匹配
func(name=value)关键字参数:通过变量名匹配
func( *name)匹配并收集(在元组中)所有包含位置的参数
func( **name)匹配并收集(在字典中)所有包含位置的参数
func( *args,name )参数必须在调用中按照关键字传递
func( *,name=value)参数必须在调用中按照关键字传递(Python3.0)
  • 关键字参数
>>> def f(a,b,c): print(a,b,c)
... 
>>> f(1,2,3)
1 2 3
>>> f(c=3,b=2,a=1)
1 2 3
>>> f(1,c=3,b=2)
1 2 3
  • 默认参数
>>> def f(a,b=2,c=3): print(a,b,c)
... 
>>> f(1)
1 2 3
>>> f(a=1)
1 2 3
>>> f(1,4)
1 4 3
>>> f(1,4,5)
1 4 5
>>> f(1,c=6)
1 2 6
  • 关键参数和默认参数
>>> def func(spam,eggs,toast=0,ham=0):
...   print((spam,eggs,toast,ham))
... 
>>> func(1,2)
(1, 2, 0, 0)
>>> func(1,ham=0,eggs=0)
(1, 0, 0, 0)
>>> func(spam=1,eggs=0)
(1, 0, 0, 0)
>>> func(toast=1,eggs=2,spam=3)
(3, 2, 1, 0)
>>> func(1,2,3,4)
(1, 2, 3, 4)
  • 收集参数
#当这个函数调用时,Python将所有位置相关的参数收集到一个新的元组中,并将这个元组赋值给变量args.
>>> def f(*args):print(args)
... 
>>> f()
()
>>> f(1)
(1,)
>>> f(1,2,3,4)
(1, 2, 3, 4)
#只对关键字参数有效,将关键字参数传传递给一个新的字典
# ** 允许将关键字参数转换为字典
>>> def f(**args):print(args)
... 
>>> f()
{}
>>> f(a=1,b=2)
{'a': 1, 'b': 2}
  • 混合参数
>>> def f(a,*pargs,**kargs): print(a,pargs,kargs)
... 
>>> f(1,2,3,x=1,y=2)
1 (2, 3) {'y': 2, 'x': 1}
  • 解包参数

在调用函数时使用 * 语法,它会解包参数集合.

>>> def func(a,b,c,d): print(a,b,c,d)
... 
>>> args = (1,2,3,4)
>>> func(*args) #解包元组
1 2 3 4
>>> def func(a,b,c,d): print(a,b,c,d)
... 
>>> args={'a':1,'b':2,'c':3} 
>>> args['d'] = 4
>>> func(**args) #解包字典,相当于关键字(name=value)参数的方式
1 2 3 4
  • 实现传递任何发送进来的参数来支持具有任意参数的任意函数.
def tracer(func,*pargs,**kargs):
print('calling:',func.__name__)
  return func(*pargs,**kargs)

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

print(tracer(func,1,2,c=3,d=4))

#运行结果:
calling: func
10

  • 实现一个函数既可以处理任意多个参数,也接受可能的配置选项.
#下面代码中,a可能按照名称或位置传递,b收集任何额外的位置参数,c必须只按照关键字传递.
#即 带* 的形参之后的参数必须通过关键字来传递.
>>> def kwonly(a,*b,c):
...   print(a,b,c)
... 
>>> kwonly(1,2,c=3)
1 (2,) 3
>>> kwonly(a=1,c=3)
1 () 3
>>> kwonly(1,2,3) #c没按关键字传递,出错了
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: kwonly() missing 1 required keyword-only argument: 'c'
#参数列表中使用一个 * 字符,表示一个函数不会接受一个任意长度的参数列表,而且 * 号之后的所有参数都以关键字形式传递
>>> def kwonly(a,*,b,c):
...   print(a,b,c)
... 
>>> kwonly(1,c=3,b=2)
1 2 3
>>> kwonly(c=3,b=2,a=1)
1 2 3
>>> kwonly(1,2,3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: kwonly() takes 1 positional argument but 3 were given
>>> kwonly(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: kwonly() missing 2 required keyword-only arguments: 'b' and 'c'
# * 后面的参数增加默认值
>>> def kwonly(a,*,b='spam',c='ham'):
...   print(a,b,c)
... 
>>> kwonly(1)
1 spam ham
>>> kwonly(1,c=3)
1 spam 3
>>> kwonly(a=1)
1 spam ham
>>> kwonly(c=3,b=2,a=1)
1 2 3
>>> kwonly(1,2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: kwonly() takes 1 positional argument but 2 were given
#接收任意长度的参数列表,但 * 号后面的参数需要关键字形式赋值
>>> def kwonly(a,*b,c='spam',d='ham'):
...   print(a,c,d)
... 
>>> kwonly(1)
1 spam ham
>>> kwonly(1,c=3)
1 3 ham
>>> kwonly(a=1)
1 spam ham
>>> kwonly(c=3,d=2,a=1)
1 3 2
>>> kwonly(1,2,3,4)
1 spam ham
  • 函数的参数不能出现在 **args任意关键字形式的后面,并且一个 ** 不能独自出现在参数列表中.
>>> def kwonly(a,**args,b,c):
  File "<stdin>", line 1
    def kwonly(a,**args,b,c):
                       ^
SyntaxError: invalid syntax
>>> def kwonly(a,**,b,c)
  File "<stdin>", line 1
    def kwonly(a,**,b,c)
                   ^
SyntaxError: invalid syntax
>>> def f(a,*b,**d,c=16): print(a,b,c,d) #**形参出现在其他形参之前,不行
  File "<stdin>", line 1
    def f(a,*b,**d,c=16): print(a,b,c,d)
                  ^
SyntaxError: invalid syntax

>>> def f(a,*b,c=6,**d): print(a,b,c,d) 
... 
>>> f(1,2,3,x=4,y=5)
1 (2, 3) 6 {'y': 5, 'x': 4}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值