Python中的5种参数类型
![](https://img-blog.csdnimg.cn/img_convert/47df2e8f945f563603a4777b0c8a246b.png)
![](https://img-blog.csdnimg.cn/img_convert/696180d073b5454d64329fbceb3bf369.png)
位置参数
调用函数时根据函数定义的参数位置来传递参数。
关键字参数
用于函数调用,通过“键-值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。
默认参数
用于定义函数,为参数提供默认值,调用函数时可传可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)。
可变参数
定义函数时
包裹位置传递
def func(*args):
....
包裹关键字传递
deffunc(**kargs):
....
解包裹参数
调用函数时
*和**,也可以在函数调用的时候使用,称之为解包裹(unpacking)
在传递元组时,让元组的每一个元素对应一个位置参数
在传递词典字典时,让词典的每个键值对作为一个关键字参数传递给函数
Python中的*和**
函数定义时参数匹配
主要作用:收集参数
*收集不匹配参数到元组中
**收集关键字参数到字典中
函数调用时解包参数
主要作用:打散参数
*用于解包元组
**用于解包字典
python中的命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了哪些,就需要在函数内部通过kw检查。
def person(name, age, **kw):
if 'city' in kw:
# 有city参数
pass
if 'job'in kw:
# 有job参数
pass
print('name:', name, 'age:', age, 'other:', kw)
如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参
def person(name, age, *, city, job):
print(name, age, city, job)
和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。
调用方式如下:
>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 BeijingEngineer
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:
def person(name, age, *args, city, job):
print(name, age, args, city, job)
命名关键字参数必须传入参数名,这和位置参数不同。
反过来说,使用命名关键字参数时,如果没有可变参数,就必须加一个*作为特殊分隔符
python中的命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了哪些,就需要在函数内部通过kw检查。
def person(name, age, **kw):
if 'city' in kw:
# 有city参数
pass
if 'job'in kw:
# 有job参数
pass
print('name:', name, 'age:', age, 'other:', kw)
如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参
def person(name, age, *, city, job):
print(name, age, city, job)
和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。
调用方式如下:
>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 BeijingEngineer
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:
def person(name, age, *args, city, job):
print(name, age, args, city, job)
命名关键字参数必须传入参数名,这和位置参数不同。
反过来说,使用命名关键字参数时,如果没有可变参数,就必须加一个*作为特殊分隔符
python函数指定数据类型
Python does not have variables, like other languages wherevariables have a type and a value; it has names pointing to objects, which knowtheir type.
However, one interesting thing haschanged since 2010 (when the question was first asked), namely theimplementation of PEP 3107 (implemented in Python 3). Youcan now actually specify the type of a parameter and the type of the returntype of a function like this:
def pick(l: list, index: int) -> int:
return l[index]
Wecan here see that picktakes 2 parameters, a list land an integer index.It should also return an integer.
Sohere it is implied that lis a list of integers which we can see without much effort, but for more
complex functions it can be a bit confusing as to what the list should contain.
We also want the default value of indexto be 0. To solve this you may choose to write picklike this instead:
def pick(l: "list of ints", index: int = 0) -> int:
return l[index]
Notethat we now put in a string as the type of l,which is syntactically allowed, but it is not good for parsing programmatically(which we'll come back to later).
Itis important to note that Python won't raise a TypeErrorif you pass a float into index,the reason for this is one of the main points in Python's design philosophy: "We're all consenting adults here",which means you are expected to be aware of what you can pass to a function andwhat you can't. If you really want to write code that throws TypeErrors you canuse the isinstance functionto check that the passed argument is of the proper type or a subclass of itlike this:
def pick(l: list, index: int = 0) -> int:
if not isinstance(l, list):
raise TypeError
return l[index]
More onwhy you should rarely do this and what you should do instead is talked about inthe next section and in the comments.
PEP3107 does not only improve code readability butalso has several fitting use cases which you can read about here.