C++里函数可以设置缺省参数,Java不可以,只能通过重载的方式来实现,python里也可以设置默认参数,最大的好处就是降低函数难度,函数的定义只有一个,并且python是动态语言,在同一名称空间里不能有想多名称的函数,如果出现了,那么后出现的会覆盖前面的函数。
def power(x, n=2): s = 1 while n > 0: n = n - 1 s = s * x return s
看看结果:
>>> power(5) 25 >>> power(5,3) 125
注意: 必选参数在前,默认参数在后,否则Python的解释器会报错。
建议:*当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
默认参数也有坑,看看下面的代码,先定义一个list,添加一个end再返回:
def add_end(L=[]): L.append('END') return L
看看调用结果:
>>> add_end([1, 2, 3]) [1, 2, 3, 'END'] >>> add_end(['x', 'y', 'z']) ['x', 'y', 'z', 'END'] >>> add_end() ['END'] >>> add_end() ['END', 'END'] >>> add_end() ['END', 'END', 'END']
这里需要解释一下,Python函数在定义的时候,默认参数L的值就被计算出来了,即[]。此时L指向[]。所以如果L中的内容改变了,下次调用引用的内容也就不再是[]了。所以要牢记一点定义默认参数必须指向不可变对象!。
可变参数
第一种方法,传入的参数为一个list或者tuple。
def calc(numbers): sum = 0 for n in numbers: sum = sum + n * n return sum
调用方式:
>>> calc([1, 2, 3]) 14 >>> calc((1, 3, 5, 7)) 84
第二种方式,直接传入多个参数,函数内部会自动用一个tuple接收。
def calc(*numbers): sum = 0 for n in numbers: sum = sum + n * n return sum
调用方式:
>>> calc(1, 2) 5 >>> calc() 0
这个时候如果还想把一个list或者tuple里的数据传进去,可以这样:
>>> nums = [1, 2, 3] >>> calc(*nums) 14
关键字参数
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def person(name, age, **kw): print 'name:', name, 'age:', age, 'other:', kw
调用示例:
>>> person('Michael', 30) name: Michael age: 30 other: {} >>> person('Bob', 35, city='Beijing') name: Bob age: 35 other: {'city': 'Beijing'} >>> person('Adam', 45, gender='M', job='Engineer') name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
参数组合
在Python中定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。
递归函数
基本的也没什么可讲的,和Java/C++里一样,就是调用本身的一种。这里重点介绍一下尾递归优化。事实上尾递归和循环效果是一样的,很显然的一个优点那就是可以防止递归调用栈溢出。
定义:在函数返回的时候调用自身,并且,return语句不能包含表达式。编译器或者解释器可以对其做优化,无论调用多少次,只占用一个栈帧,不会出现溢出的情况。
举个简单的例子,以阶乘函数为例:
def fact(n): if n==1: return 1 return n * fact(n - 1)
如果传入的n很大,就可能会溢出,这是由于return n * fact(n - 1)引入了乘法表达式,就不是尾递归了。把代码改一下:
def fact(n): return fact_iter(n, 1) def fact_iter(num, product): if num == 1: return product return fact_iter(num - 1, num * product)
默认参数陷阱
Python的函数定义提供了默认参数这个选择,使得函数的定义和使用更加的灵活,但是也会带来一些坑,例如之前的一个例子:
函数定义:
def add_end(L=[]): L.append('END') return L
调用函数的结果:
>>> add_end([1, 2, 3]) [1, 2, 3, 'END'] >>> add_end(['x', 'y', 'z']) ['x', 'y', 'z', 'END'] >>> add_end() ['END'] >>> add_end() ['END', 'END'] >>> add_end() ['END', 'END', 'END']
很明显这个与函数的定义初衷不符,用一句话解释就是:
Default values are computed once, then re-used.
为了深入研究这个问题,我们来看看另一个例子:
# coding=utf-8 def a(): print "a executed" return [] def b(x=a()): print "id(x):", id(x) x.append(5) print "x:", x for i in range(2): print "不带参数调用,使用默认参数" b() print b.__defaults__ print "id(b.__defaults__[0]):", id(b.__defaults__[0]) for i in range(2): print "带参数调用,传入一个list" b(list()) print b.__defaults__ print "id(b.__defaults__[0]):", id(b.__defaults__[0])
NOTE:稍微解释一下,所有默认值都存储在函数对象的__defaults__属性中,这是一个列表,每一个元素均为一个默认参数值。
来看看输出结果:
a executed 不带参数调用,使用默认参数 id(x): 140038854650552 x: [5] ([5],) id(b.__defaults__[0]): 140038854650552 不带参数调用,使用默认参数 id(x): 140038854650552 x: [5, 5] ([5, 5],) id(b.__defaults__[0]): 140038854650552 带参数调用,传入一个list id(x): 140038854732400 x: [5] ([5, 5],) id(b.__defaults__[0]): 140038854650552 带参数调用,传入一个list id(x): 140038854732472 x: [5] ([5, 5],) id(b.__defaults__[0]): 140038854650552
简单分析一下输出结果:
第1行
在定义函数b(),即执行def语句,代码第7行def b(x=a()):的时候,这句话使用了默认参数,所以在定义的时候会计算默认参数x的值,这个时候会调用a(),所以打印出了a executed。
第2~6行
第一次执行循环,代码第14行调用b()没有传递参数,使用默认参数,此时x=[],所以调用一次之后
print b.__defaults__
输出结果为
([5],)
print b.__defaults__
输出结果为
([5, 5],)
第12~16行
第二个循环语句,第一次循环,代码第20行传入一个空的list,所以不使用默认参数,此时x=[],所以
print b.__defaults__
输出结果为
([5],)
print b.__defaults__
输出结果依然为
([5],)
# coding=utf-8 def a(): print "a executed" return None def b(x=a()): print "id(x):", id(x) if x is None: x = [] x.append(5) print "x:", x for i in range(2): print "不带参数调用,使用默认参数" b() print b.__defaults__ print "id(b.__defaults__[0]):", id(b.__defaults__[0]) for i in range(2): print "带参数调用,传入一个list" b(list()) print b.__defaults__ print "id(b.__defaults__[0]):", id(b.__defaults__[0])
此时的输出结果看看是什么:
a executed 不带参数调用,使用默认参数 id(x): 9568656 x: [5] (None,) id(b.__defaults__[0]): 9568656 不带参数调用,使用默认参数 id(x): 9568656 x: [5] (None,) id(b.__defaults__[0]): 9568656 带参数调用,传入一个list id(x): 140725126699632 x: [5] (None,) id(b.__defaults__[0]): 9568656 带参数调用,传入一个list id(x): 140725126699704 x: [5] (None,) id(b.__defaults__[0]): 9568656
本文向大家介绍实例讲解在C++的函数中变量参数及默认参数的使用,包括了实例讲解在C++的函数中变量参数及默认参数的使用的使用技巧和注意事项,需要的朋友参考一下 包含变量参数列表的函数 如果函数声明中最后一个成员是省略号 (...),则函数声明可采用数量可变的参数。在这些情况下,C++ 只为显式声明的参数提供类型检查。即使参数的数量和类型是可变的,在需要使函数泛化时也可使用变量参数列表。函数的系列是
我想定义一个特征,它告诉一个复杂的表示形式是否是一个结构数组,其中的实际值从来不是AoS,因此不需要用户定义的指定,但对于复杂的表示形式,您总是需要一个: 专门化是通过从std::true/false_type派生而以std方式完成的。 问题是:使用这个实现,我会得到“template argument invidents template parameter”错误(在链接的问题中解释了这一点),
问题内容: 我对PHP函数的默认值感到困惑。说我有一个这样的功能: 如果我想为$ x使用默认参数并为$ y设置不同的参数怎么办? 我一直在尝试不同的方法,但我变得更加困惑。例如,我尝试了以下两种方法: 但是这两个都不会为$ x产生适当的默认参数。我也试图通过变量名来设置它。 我完全希望这样的事情能奏效。但这根本不符合我的预期。似乎不管我做什么,每次调用该函数时,无论如何我都必须最终键入默认参数。而
本文向大家介绍Python进阶-函数默认参数(详解),包括了Python进阶-函数默认参数(详解)的使用技巧和注意事项,需要的朋友参考一下 一、默认参数 python为了简化函数的调用,提供了默认参数机制: 这样在调用pow函数时,就可以省略最后一个参数不写: 在定义有默认参数的函数时,需要注意以下: 必选参数必须在前面,默认参数在后; 设置何种参数为默认参数?一般来说,将参数值变化小的设置为默认
在 C++中,定义函数时可以给形参指定一个默认的值,这样调用函数时如果没有给这个形参赋值(没有对应的实参),那么就使用这个默认的值。也就是说,调用函数时可以省略有默认值的参数。如果用户指定了参数的值,那么就使用用户指定的值,否则使用参数的默认值。 所谓默认参数,指的是当函数调用中省略了实参时自动使用的一个值,这个值就是给形参指定的默认值。下面是一个简单的示例: 运行结果: 10, 3.5, # 2
我们知道,在调用函数时如果不指定某个参数, Python 解释器会抛出异常。为了解决这个问题,Python 允许为参数设置默认值,即在定义函数时,直接给形式参数指定一个默认值。这样的话,即便调用函数时没有给拥有默认值的形参传递参数,该参数可以直接使用定义函数时设置的默认值。 Python 定义带有默认值参数的函数,其语法格式如下: def 函数名(...,形参名,形参名=默认值): 代码块