1、所有的函数都有返回值, 如果有return语句 则执行 return语句,如没有则返回None。
#没有返回值的函数,其实返回的是None
def run(name):
print name,'runing' '#函数体语句从下一行开始,并且第一行必须是缩进的'
>>>run('xiaoming')
xiaoming runing
>>>print run('xiaoming')
xiaoming runing
None '#如果没有ruturn语句,函数返回的是None'
'#有返回值的参数'
def run(name):
return name+'runing'
>>>r = run('xiaoming')
>>>r
xiaoming runing
1、 如果一个函数的参数中含有默认参数,则这个默认参数后的所有参数都必须是默认参数 ,否则会抛出:SyntaxError: non-default argument follows default argument的异常。
def run(name,age=10,sex):
print name ,age ,sex
SyntaxError: non-default argument follows default argument
2、调用的四种错误。( 只要你有一个命名参数,它右边的所有参数也都需要是命名参数)
def run(name,age,sex='boy'):
print name,age,sex
>>>run() #TypeError: run() missing 2 required positional arguments: 'name' and 'age'
>>>run(name='gg',23) #SyntaxError: positional argument follows keyword argument
>>>run('gg',name='pp')#TypeError: run() got multiple values for argument 'name'
>>>run(actor='xxxx') #TypeError: run() got an unexpected keyword argument 'actor'
第一种情况是丢失参数
第二种情况是:如果第一个使用了keyword绑定,后面的都必须使用keyword绑定 ?
第三种情况:在一次调用中不能同时使用位置和keyword绑定
第四种情况:不能使用参数列表外的关键字
2、默认参数在函数定义段被解析,且只解析一次 。
>>>i = 5
>>>def f(arg=i):
>>> print arg
>>>i = 6
>>>f()
5 结果是5
image.png
感觉这里有认知错误:这里并不是只解析一次,而是这样调用i=6是错误的,函数只会在函数体上方查找i的值, 而不是从调用处(f())上面。
当默认值是一个可变对象,诸如链表、字典或大部分类实例时,会产生一些差异:
>>> def f(a, L=[]):
>>> L.append(a)
>>> return L
>>> print f(1)
>>> print f(2)
>>> print f(3)
[1]
[1, 2]
[1, 2, 3]
#可以用另外一种方式实现:
>>> def f(a, L=None):
>>> if L is None:
>>> L = []
>>> L.append(a)
>>> return L
3.1参数列的分拆:在使用可变数量的位置参数的函数时,可使用序列拆分操作符(*)
>>> args =[3,6]
>>> range(*args)
range(3, 6)
----------------------------
>>> a = [3,20,2]
>>> range(*a)
range(3, 20, 2)
——————————————————————————————————————————————
>>> a = [3,20,2,6]
>>> range(*a)
Traceback (most recent call last):
File "<pyshell#49>", line 1, in <module>
range(*a)
TypeError: range expected at most 3 arguments, got 4
实验1:
>>> def product(*args,po):
result = 1
for arg in args:
result *= arg
print(result+po)
>>> product(1,2,3,4)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
product(1,2,3,4)
TypeError: product() missing 1 required keyword-only argument: 'po'
>>> def product(*args,po=1):
result = 1
for arg in args:
result *= arg
print(result+po)
>>> product(1,2,3,4)
25
实验2:* 本身作为参数 (这里 * 的作用是什么 没有搞清楚, 我感觉像是阻止乱传参数用的)
def heron(a,b,c,*,unit="meters"):
print('----------')
>>> heron(1,2,3)
----------
>>> def heron(a,b,c,*,unit):
print('---------')
>>> heron(1,2,3,unit='dfd') `#可以这样传参数`
---------
>>>
>>> heron(1,2,3,4)
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
heron(1,2,3,4)
TypeError: heron() takes 3 positional arguments but 4 were given
>>> heron(1,2,3)
Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
heron(1,2,3)
TypeError: heron() missing 1 required keyword-only argument: 'unit'
>>> heron(1,3,4,5)
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
heron(1,3,4,5)
TypeError: heron() takes 3 positional arguments but 4 were given
如果将* 作为第一个参数,那么不允许使用任何位置参数,并强制调用该函数时使用关键字参数:def print_set(*,paper="Letter",copies=1,color=False):...。可以不使用任何参数调用 print_set(),也可以改变某些或全部默认值。但如果使用位置参数,就会产生TypeError异常,比如print_set(“A4”)就会产 生异常。
>>> def print_set(*,paper="Letter",copies=1,color=False):
print('7452347')
>>> print_set()
7452347
>>> print_set(paper='djfa;lsd')
7452347
3.2、对映射进行拆分时,可使用映射拆分操作符(**)
3.3、总结: 不定长参数
def test(*arg,**kwargs):
print arg
print kwargs
print "-------------------"
if __name__=='__main__':
test(1,2,3,4,5)
test(a=1,b=2,c=3)
test(1,2,3,a=1,b=3,c=5)
output:
(1, 2, 3, 4, 5)
{}
()
{'a': 1, 'c': 3, 'b': 2}
(1, 2, 3)
{'a': 1, 'c': 5, 'b': 3}
扩展:non-keyword arg after keyword arg
在Python中,这两个是python中的可变参数,arg表示任意多个无名参数,类型为 tuple,*kwargs表示关键字参数,为dict,使用时需将 *arg放在 **kwargs之前,否则会有“SyntaxError: invalid syntax”的语法错误
4、匿名函数
>>> def make_incrementor(n):
... return lambda x: x + n #相当于创建了一个一x为参数的匿名函数?
...
>>> f = make_incrementor(42)#f = make_incrementor(n=42),设置n的值
>>> f(0)#其实调用的是匿名函数?
42
>>> f(1)
43
网友评论