- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Python中的函数参数(位置参数、默认参数、可变参数)由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
函数的参数:Python中函数定义非常简单,由于函数参数的存在,使函数变得非常灵活应用广泛;不但使得函数能够处理复杂多变的参数,还能简化函数的调用.
Python中的函数参数有如下几种:位置参数、默认参数、可变参数、关键字参数和命名关键字参数 。
位置参数(positional arguments)就是其他语言的参数,其他语言没有分参数的种类是因为只有这一种参数, 所有参数都遵循按位置一一对应的原则 .
计算x^2 的函数:
1
2
3
|
def
power(x):
return
x
*
x
power(
2
)
|
对于power(x) 函数,参数x就是一个 位置参数 ,也叫做 必选参数 。当我们调用power函数时,必须传入有且仅有的一个参数x.
现在,如果我们要计算 x^3 怎么办?可以再定义一个power3 函数,但是如果要计算 x^4 、 x^5 ……怎么办?我们不可能定义无限多个函数.
你也许想到了,可以把power(x) 修改为power(x, n) ,用来计算 x^n ,说干就干:
1
2
3
4
5
6
|
def
power(x,n):
s
=
1
while
n >
0
:
s
=
s
*
x
n
=
n
-
1
return
s
|
对于这个修改后的power(x, n) 函数,可以计算任意n次方 。
1
2
|
print
(power(
2
,
10
))
print
(power(
1
,
10
))
|
输出:
1024 。
1 。
修改后的power(x, n) 函数有两个参数:x和n,这两个参数都是位置参数,调用函数时,传入的两个值 按照位置顺序 依次赋给参数x 和n .
由于我们经常计算 x^2 ,所以,完全可以把第二个参数n 的默认值设定为2,这个时候,默认参数就派上用场了.
1
2
3
4
5
6
7
8
9
|
def
power(x,n
=
2
):
s
=
1
while
n >
0
:
s
=
s
*
x
n
=
n
-
1
return
s
print
(power(
4
))
print
(power(
3
,n
=
3
))
print
(power(
2
,
4
))
|
输出:
16 。
27 。
16 。
这样,当我们调用power(4) 时,相当于调用power(4, 2) :而对于n > 2 的其他情况,就必须明确地传入n ,比如power(2, 4) .
从上面的例子可以看出, 默认参数可以简化函数的调用 .
设置默认参数时,有几点要注意:
1、必选参数(位置参数)在前,默认参数在后,否则Python的解释器会报错 。
2、当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数 。
使用默认参数有什么好处?
举个例子,我们写个一年级小学生注册的函数,需要传入name 、gender 、age、city四个参数:
由于大多数学生注册时年龄和城市基本一样,就可以把年龄和城市设置为默认参数,这样,大多数学生注册时不需要提供年龄和城市,只提供必须的两个参数,只有与默认参数不符的学生才需要提供额外的信息.
1
2
3
4
5
6
7
8
9
10
11
|
#学籍输入
def
enroll(name,gender,age
=
6
,city
=
'BJ'
):
print
(
'name is: '
,name)
print
(
'gender is: '
,gender)
print
(
'age is: '
,age)
print
(
'city is: '
,city,
'\n'
)
enroll(
'Tom'
,
'M'
)
enroll(
'Lisa'
,
'f'
)
enroll(
'Bob'
,
'M'
,
7
)
enroll(
'Lucy'
,
'F'
,
7
,
'TJ'
)
enroll(
'Jerry'
,
'M'
,city
=
'SH'
)
|
输出:
name is: Tom 。
gender is: M 。
age is: 6 。
city is: BJ 。
name is: Lisa 。
gender is: f 。
age is: 6 。
city is: BJ 。
name is: Bob 。
gender is: M 。
age is: 7 。
city is: BJ 。
name is: Lucy 。
gender is: F 。
age is: 7 。
city is: TJ 。
name is: Jerry 。
gender is: M 。
age is: 6 。
city is: SH 。
可见,默认参数降低了函数调用的难度,而一旦需要更复杂的调用时,又可以传递更多的参数来实现。无论是简单调用还是复杂调用,函数只需要定义一个.
注意:默认参数有个最大的坑,演示如下:
先定义一个函数,传入一个list,添加一个end 再返回:
1
2
3
|
def
add_end(
list
=
[]):
list
.append(
'end'
)
return
list
|
当你正常调用时,结果似乎不错:
1
2
|
print
(add_end([
1
,
2
,
3
]))
print
(add_end([
'x'
,
'y'
]))
|
输出:
[1, 2, 3, 'end'] 。
['x', 'y', 'end'] 。
1
2
3
4
5
|
#当你使用默认参数调用时,一开始结果也是对的:
print
(add_end())
#但是,再次调用add_end() 时,结果就不对了:
print
(add_end())
print
(add_end())
|
输出:
['end'] 。
['end', 'end'] 。
['end', 'end', 'end'] 。
很多初学者很疑惑,默认参数是[] ,但是函数似乎每次都“记住了”上次添加了'end' 后的list。原因解释如下:
Python函数在定义的时候,默认参数list的值就被计算出来了,即[] ,因为默认参数list也是一个变量,它指向对象[] ,每次调用该函数,如果改变了list的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了.
定义默认参数要牢记一点:默认参数必须指向不变对象! 。
因此定义默认参数时一定要使用不可变对象(int、float、str、tuple)。使用可变对象语法上没错,但在逻辑上是不安全的,代码量非常大时,容易产生很难查找的bug.
要修改上面的例子,我们可以用None 这个不变对象来实现:
1
2
3
4
5
6
7
8
9
10
|
def
add_end(
list
=
None
):
if
list
=
=
None
:
list
=
[]
list
.append(
'end'
)
return
list
print
(add_end([
1
,
2
,
3
]))
print
(add_end([
'x'
,
'y'
]))
print
(add_end())
print
(add_end())
print
(add_end())
|
输出:
[1, 2, 3, 'end'] 。
['x', 'y', 'end'] 。
['end'] 。
['end'] 。
['end'] 。
现在,无论调用多少次,都不会有问题.
为什么要设计str 、 None 这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象.
在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个.
我们以数学题为例子,给定一组数字a,b,c…… ,请计算a^2 + b^2 + c^2 +... 。
要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:
1
2
3
4
5
6
7
|
def
calculator(numbers):
sum
=
0
for
n
in
numbers:
sum
=
sum
+
n
*
n
return
sum
print
(calculator([
2
,
3
]))
print
(calculator((
3
,
5
,
6
)))
|
输出:
13 。
70 。
但是调用的时候,需要先组装出一个list 或tuple,如果利用可变参数,调用函数的方式就可以简化:
1
2
3
4
5
6
7
|
def
calculator(
*
numbers):
sum
=
0
for
n
in
numbers:
sum
=
sum
+
n
*
n
return
sum
print
(calculator(
2
,
3
))
print
(calculator(
3
,
5
,
6
))
|
输出:
13 。
70 。
定义可变参数和定义一个list 或tuple 参数相比,仅仅在参数前面加了一个* 号。在函数内部,参数numbers接收到的是一个tuple(可变参数将以tuple形式传递),因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数.
如果已经有一个list或者tuple,要调用一个可变参数怎么办?可以这样做:
1
2
|
nums
=
[
2
,
3
,
4
]
print
(calculator(nums[
0
],nums[
1
],nums[
2
]))
|
输出:
29 。
这种写法当然是可行的,问题是太繁琐,所以Python允许你* 在list或tuple前面加一个 号**,把list或tuple的元素变成可变参数传进去:
1
2
|
nums
=
[
2
,
3
,
4
]
print
(calculator(
*
nums))
|
输出:
29 。
nums 表示把nums 这个list的所有元素作为可变参数传进去。这种写法相当有用,而且很常见.
python的可变参数以tuple形式传递,而关键字参数则是以dict形式传递.
即可变参数传递的是参数值,关键字参数传递的是参数名:参数值键值对.
形式: **kw 这是惯用写法,建议使用,容易被理解 。
1
2
3
4
|
def
stu_info(name,gender,
*
*
kw):
print
(
'name is:'
,name,
' gender is:'
,gender,
' other is :'
,kw)
stu_info(
'Bob'
,
'M'
,age
=
7
,city
=
'TJ'
)
stu_info(
'Lucy'
,
'F'
,city
=
'BJ'
)
|
输出:
name is: Bob gender is: M other is : {'age': 7, 'city': 'TJ'} 。
name is: Lucy gender is: F other is : {'city': 'BJ'} 。
可变参数和关键字参数都可以接受0个或者多个参数 。
Python的命名关键字参数对传入的关键字参数做了进一步的限制.
格式:在关键字参数前增加一个”*”.
1
2
3
4
|
def
stu_info(name,gender,
*
,age,city):
print
(
'name is:'
,name,
' gender is:'
,gender,
' age:'
,age,
' city:'
,city)
stu_info(
'Bob'
,
'M'
,age
=
7
,city
=
'TJ'
)
stu_info(
'Lucy'
,
'F'
,city
=
'BJ'
,age
=
10
)
|
输出:
name is: Bob gender is: M age: 7 city: TJ 。
name is: Lucy gender is: F age: 10 city: BJ 。
* 关键字参数和命名关键字参数的区别在于,前者可以传递任何名字的参数,而后者只能传递 后面名字的参数。* 如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符 了:
1
2
3
4
5
6
7
|
#args可以传递一个tuple 其后只能传递age和city参数
def
stu_info(name,gender,
*
args,age,city):
print
(
'name is:'
,name,
' gender is:'
,gender,
' age:'
,age,
' city:'
,city)
for
i
in
args:
print
(
'args:'
,i)
stu_info(
'Bob'
,
'M'
,age
=
7
,city
=
'TJ'
)
stu_info(
'Lucy'
,
'F'
,(
2
,
3
),city
=
'BJ'
,age
=
10
)
|
输出:
name is: Bob gender is: M age: 7 city: TJ 。
name is: Lucy gender is: F age: 10 city: BJ 。
args: (2, 3) 。
一次函数调用可以传递以上所述任何一种参数或者多种参数的组合,当然也可以没有任何参数。正如默认参数必须在最右端一样,使用多种参数时也对顺序有严格要求,也是为了解释器可以正确识别到每一个参数.
顺序:位置参数、默认参数、可变参数、命名关键字参数和关键字参数.
1
2
|
def
function(a, b, c
=
0
,
*
, d,
*
*
kw):
print
(
'a ='
, a,
'b ='
, b,
'c ='
, c,
'd ='
, d,
'kw ='
, kw)
|
可读性是代码的一个很重要的要求,所以尽量避免使用多种参数的组合.
到此这篇关于Python中的多个函数参数的文章就介绍到这了,更多相关Python中的函数参数内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://blog.51cto.com/u_5839280/3799375 。
最后此篇关于Python中的函数参数(位置参数、默认参数、可变参数)的文章就讲到这里了,如果你想了解更多关于Python中的函数参数(位置参数、默认参数、可变参数)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!