函数基础
函数定义使用def functionname(variable…): 根据同一代码块的规则,所属该函数的代码需要每行前面空出几个空格,下放一个简单的函数
def add(a,b):
return a+b
result = add(1,2)
print(result)
简单定义了一个add函数,a,b为函数参数,return 将函数执行结果返回;可以使用一个变量接受函数返回的参数;没有return语句的,则默认函数返回null
python3中也提供了很多的内置函数,如dir 查看所有的方法名;help函数,查看帮助文档;
函数调用方式除了使用add(a,b),可以使用,也可以设置传入参数默认值
函数设定默认值
在定义函数时参数写为 参数名=默认值1,参数名=默认值2…的方式,说明方法被定义了默认值,因此再调用时可以不传带有默认值的参数时仍可正常执行;但是需要注意的是带默认值需要写在后面
>>> def add(a=1,b=3):
return a+b
>>> add(2,3)
5
>>> add(2)
5
>>> add()
4
>>> def add(a=1,b):
return a+b
SyntaxError: non-default argument follows default argument
>>> def add(a,b=3):
return a+b
>>> add(0)
3
>>>
函数参数不确定
如果当前函数不确定需要几个参数时如何处理呢,参数收集方式,在参数名前加一个“*”
>>> def print2(a,b,*args):
print("a=",a)
print("b=",b)
print("args=",args)
>>> print2(1,2,4,5,6,9)
a= 1
b= 2
args= (4, 5, 6, 9)
>>> print2(1,2,"a","b","c","c")
a= 1
b= 2
args= ('a', 'b', 'c', 'c')
>>>
最终不定个数的参数传入参数会被放在args元组中,当然还有另一种方式,在参数名前加两个"**"如下:
>>> def print2(a,b,**args):
print("a=",a)
print("b=",b)
print("args=",args)
>>> print2(1,2,a=3,b=4,d=7,n=9)
Traceback (most recent call last):
File "<pyshell#60>", line 1, in <module>
print2(1,2,a=3,b=4,d=7,n=9)
TypeError: print2() got multiple values for argument 'a'
>>> print2(1,2,a1=3,b1=4,d=7,n=9)
a= 1
b= 2
args= {'a1': 3, 'b1': 4, 'd': 7, 'n': 9}
>>>
函数嵌套
在函数的参数也可以是具体的方法
>>> def con_seq(func,seq):
r = [func(i) for i in seq]
return r
>>> con_seq(abs,range(-10,3))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2]
>>> con_seq(str,range(-10,3))
['-10', '-9', '-8', '-7', '-6', '-5', '-4', '-3', '-2', '-1', '0', '1', '2']
>>> con_seq(ord,"python")
[112, 121, 116, 104, 111, 110]
>>>
内部嵌套函数
>>> def con1(x):
def con2(y):
return x*y
return con2
>>> f1 = con1(10)
>>> r1 = f1(20)
>>> r1
200
>>>
作用域问题
>>> r1
200
>>> def f1():
print(r1+1)
>>> f1()
201
>>> def f2():
r1=r1+1
print(r1)
>>> f2()
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
f2()
File "<pyshell#25>", line 2, in f2
r1=r1+1
UnboundLocalError: local variable 'r1' referenced before assignment
但是当我们使用global语句去装饰r1,才能在内部去更改r1的值,我们重写f2方法,从下方的的输出可以看出,执行f2后就更改了外部变量r1的值
>>> def f2():
global r1
r1=r1+1
print(r1)
>>> f2()
201
>>> f1
<function f1 at 0x000001365D9BCE50>
>>> r1
201
>>> f2()
202
>>> r1
202
同样如果在嵌套的函数中处理参数,需要更改值时示例代码如下:
>>> def f3():
r2 = 1
def f4():
r2 = r2+1
print(r2)
f4()
>>> f3()
Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
f3()
File "<pyshell#42>", line 6, in f3
f4()
File "<pyshell#42>", line 4, in f4
r2 = r2+1
UnboundLocalError: local variable 'r2' referenced before assignment
>>> def f3():
r2 = 1
def f4():
nonlocal r2
r2 = r2+1
print(r2)
f4()
>>> f3()
2
lambda表达式
用lambda表达式创建匿名函数,不过一般只用于简单的逻辑函数,下方介绍其他函数时穿插该表达式的应用
>>> f6 = lambda x:x+1
>>> f6(5)
6
>>>
特殊函数map
map(func,*iterables),将多个可迭代对象的元素作为参数执行func方法,而且func中的参数个数,要与可迭代对象参数个数保持一致
>>> m = map(lambda x:x+1000,range(10))
>>> m
<map object at 0x000001365D9BB760>
>>> list(m)
[1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009]
>>> m = map(lambda x:x+1000,range(10),range(10))
>>> m
<map object at 0x000001365D9BB970>
>>> list(m)
Traceback (most recent call last):
File "<pyshell#70>", line 1, in <module>
list(m)
TypeError: <lambda>() takes 1 positional argument but 2 were given
特殊函数filter
filter过滤函数filter(func or None,iterable),其实该函数在使用过程中和map一样很是实用,下方给一个简单的示例,0-20不包括20以内被2整除的整数数字;注意filter第二个参数为单个可迭代对象,不像map可以传入多个可迭代对象参数
>>> fil = filter(lambda x:x%2==0,range(0,20))
>>> fil
<filter object at 0x000001365D9BB4F0>
>>> list(fil)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
特殊函数sorted
sorted函数sorted(iterable, /, *, key=None, reverse=False)。此时lambda函数用于指定对列表中所有元素进行排序的准则;而该函数在复杂程序中应用也非常多
原始的文档介绍如下:
一个自定义关键函数可以用来自定义排序规则,而默认反转标记可以将结果按照降序排列
A custom key function can be supplied to customize the sort order, and the
reverse flag can be set to request the result in descending order.
>>> sor = sorted(range(0,20),key=lambda x:abs(x-10))
>>> sor
[10, 9, 11, 8, 12, 7, 13, 6, 14, 5, 15, 4, 16, 3, 17, 2, 18, 1, 19, 0]
>>> sor = sorted(range(0,20),key=lambda x:abs(x-10),reverse=True)
>>> sor
[0, 1, 19, 2, 18, 3, 17, 4, 16, 5, 15, 6, 14, 7, 13, 8, 12, 9, 11, 10]
特殊函数reduce
此时lambda函数用于指定列表中两两相邻元素的结合条件;
reduce(function, sequence[, initial]) -> value
但是在python3中reduce被移到functools模块中,因此在使用时需要引入模块
from functools import reduce
>>> reduce(lambda x,y:x+y,range(0,20))
190
>>> reduce(lambda x,y:"{},{}".format(x,y),range(0,20))
'0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19'
装饰器
>>> def bk(name):
return "a+b+c={}".format(name)
>>> def bk_f(func):
def wrapper(name):
return "<p>{}</p>".format(func(name))
return wrapper
>>> bk_1 = bk_f(bk);
>>> bk_2 = bk_1("我说")
>>> bk_2
'<p>a+b+c=我说</p>'
>>>
而另一种写法,使用@bk_f放在在bk函数的上面,示例输出如下
>>> def bk_f(func):
def wrapper(name):
return "<p>{}</p>".format(func(name))
return wrapper
>>> @bk_f
def bk(name):
return "a+b+c={}".format(name)
>>> bk_2 = bk("我说")
>>> bk_2
'<p>a+b+c=我说</p>'
>>>
我们发现当使用@bk_f之后,我们不需要像之前那样先去调用bk_f方法,只需要正常执行bk方法即可输出与之前相同的结果,那如果在多加一个呢
>>> def bk_f(func):
def wrapper(name):
return "<p>{}</p>".format(func(name))
return wrapper
>>> def bk_g(func):
def wrapper(name):
return "<div>{}</div>".format(func(name))
return wrapper
>>> @bk_g
@bk_f
def bk(name):
return "a+b+c={}".format(name)
>>> bk_2 = bk("知道吗")
>>> bk_2
'<div><p>a+b+c=知道吗</p></div>'
>>>