(本文是廖雪峰Python教程的学习总结)
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”:
a = abs
a(-1)
当需要用户交互输入时,input函数默认的类型是int或者float型,raw_input默认的输入类型是str型。
空函数:
def nop():
pass
pass可以用来作为一个占位符,用于目前还不确定函数的功能 以备后面扩展使用。
函数可以返回多值
例如: def fun(x,y):
return x+y,x-y
函数返回多个值时实际返回的是一个元组,比如上面的函数,当调用fun(2,1)时返回的是(3,1)
函数的参数
位置参数:例如上面的fun(x,y)函数中的x,y就是函数的位置参数,传入参数时按照顺序依次传入。
默认参数:例如现在定义一个函数用于计算x的n次方
def power(x,n):
r = 1
while n>0:
r = r * x
n = n - 1
return r
正常调用power函数必须要传入两个参数,当我们想要默认这个是计算一个数平方时,就可以把n设置成默认参数,这样传入一个参数时就会默认计算是这个数的平方。 设置n=2默认参数的方式是:power(x,n=2)
设置默认参数要遵循:必选参数在前,默认参数在后;默认参数一定要指向不变对象
设置默认参数的好处是可以降低函数的调用复杂度,在实际开发中函数的参数个数可能会有变化,但是我们又不想重新定义一个函数来实现,这个时候就可以通过设置默认参数的方式来实现。
关于设置默认参数的原则:一定要指向不变对象。这句话怎么理解? 有下面例子:
def add_end(L=[]):
L.append('END')
return L
add_end()
print add_end()
add_end()函数参数L的默认参数设置为一个空list,函数的作用是在L的末尾添加‘END’字符串。当我们运行上面代码时 打印的输出是['END','END'] 程序仿佛记忆住了上次传入的参数[], 出现这个现象的原因是,当函数创建的时候,默认参数L指向了一个对象[],每次调用函数时,改变了这个对象的内容,下次再调用时默认参数依然指向这个已经改变了的对象,不再是指向函数定义时候的[]了。修正这个错误可以修改为:
def add_end(L=None):
if L==None:
L = []
L.append('END')
return L
print add_end()
print add_end()
None是一个不可变对象,所以不会有上面的问题。
可变参数
现在我们要计算a+b+c+...的值。具体是多少个参数的和不确定,一种方法是传入参数是一个list,实现方法如下:
def sum_integer(mylist):
mysum = 0
for i in mylist:
mysum = mysum + i
return mysum
print sum_integer([1,2,3,4,5])
函数调用时需要把各个元素组成一个list或者tuple
用可变参数函数可以写为:
def sum_integer(*nums):
mysum = 0
for i in nums:
mysum = mysum + i
return mysum
print sum_integer(1,2,3,4,5)
和用list和tuple相比,可变参数的使用时在参数前面加了一个*.在函数内部nums接收到的是一个tuple,因此主体代码和使用list是完全一样的。如果已经有一个list或者tuple,python允许在他们之前加一个* 作为可变参数传入,例如sum_integer(*[1,2,3,4,5]).
关键字参数
关键字参数允许输入0个或任意个含有参数名的参数,这些参数在函数内部自动组装成dict。含关键字参数的一个例子:
def person(name, age, **other):
print 'name:',name,'age:',age,'others:',other
person('jane','27',city='beijing',job='engineer')
**other即为关键字参数,代码中传入的关键字参数city=‘beijing’ job=‘engineer’会组成一个dict,所以上面的函数输出为:
name: jane age: 27 others: {'city': 'beijing', 'job': 'engineer'}
关键字参数在扩展函数功能时很有用,可以任意增加其他的参数
关键字参数也可以直接传入dict结构,以上面为例,调用person也可以使用:
person('jane','27',**{'city' : 'beijing', 'job' : 'engineer'})
命名关键字参数
上面的例子中可输入任意数量的参数,如果想要加以限制参数就要用到命名关键字参数。如果上面例子中只支持city和job参数
def person(name, age, *, city, job): *之后的参数视为关键字参数。 注:这个功能在2.7版本中貌似不支持
如果函数中已经有一个可变参数,则后面的命名关键字参数就不需要*分隔符。
关键字参数必须传入参数名即如果是直接调用person('jane','27','beijing', 'engineer')则会报错
参数组合
上面的几种参数可以组合使用
def f_test(a, b, c=3, *args, **num):
print 'a:',a,'b:',b,'c:',c,'agrs:',args,'num:',num
f_test(1,2,3,4,5,a1='12',b1='13')
上面的输出为 a: 1 b: 2 c: 3 agrs: (4, 5) num: {'a1': '12', 'b1': '13'}
值得注意的是上面调用都可以用tuple和dict实现
f_test(*(1,2,3,4,5), **{'a1':'12','b1':'13'})
对于任何函数都可以通过func(*args, **kw)的形式调用