Ⅰ.函数
0x00 什么是函数
Python 中函数的应用非常广泛。
前面章节中我们已经接触过多个函数,比如 input() 、print()、range()、len() 函数等等,
这些都是 Python 的内置函数,可以直接使用。
除了可以直接使用的内置函数外,Python 还支持自定义函数,即将一段有规律的、可重复使用的代码定义成函数,从而达到一次编写、多次调用的目的。
0x01 举个栗子
在前面,我们学习了 len() 函数,len() 函数的主要作用就是获取字符串、列表...的长度
我们不妨设想一下,假如没有 len() 函数,我们要怎么获取一个字符串的长度呢?
这里只考虑最简单的,方便学习(笔者只是想要偷懒 )
s = "Hello" # 待处理字符串
l = 0 # 字符串长度变量
for _ in s: # _ 表示没有遍历变量,省略这个
l += 1 # 累加长度
print(l)
执行结果:
代码完美运行 ,真不愧是我,哈哈哈!(自恋中)
要知道,获取一个字符串长度是常用的功能,一个程序中就可能用到很多次,如果每次都写这样一段重复的代码,不但费时费力、容易出错,而且交给别人时也很麻烦。
所以 Python 提供了一个功能,即允许我们将常用的代码以固定的格式封装(包装)成一个独立的模块,只要知道这个模块的名字就可以重复使用它,这个模块就叫做函数(Function)。
比如,在程序中定义了一段代码,这段代码用于实现一个特定的功能。
问题来了,如果下次需要实现同样的功能,难道要把前面定义的代码复制一次?如果这样做实在太傻了,这意味着每次当程序需要实现该功能时,都要将前面定义的代码复制一次。正确的做法是,将实现特定功能的代码定义成一个函数,每次当程序需要实现该功能时,只要执行(调用)该函数即可。
其实,函数的本质就是一段有特定功能、可以重复使用的代码,这段代码已经被提前编写好了,并且为其起一个“好听”的名字。在后续编写程序过程中,如果需要同样的功能,直接通过起好的名字就可以调用这段代码。
接下来我们就要学习如何创建一个函数
0x02 创建函数
python 中创建函数需要使用 def 关键字,基本规则如下如下
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
基本格式如下:
def 一个美丽的函数(参数列表): # 没错,中文函数名也是可以的
... # 代码块
return 返回值 # 如果有返回值的话
一个美丽的函数() # 调用函数
接下来,到我们大展身手的时候了
让我们把刚才获取字符串长度的功能封装成一个函数吧。
def getStrLen(): # 这里使用小驼峰命名法
l = 0 # 字符串长度变量
for _ in s: # _ 表示没有遍历变量,省略这个
l += 1 # 累加长度
print(l)
这里是访问全局变量s,并打印s的长度
额,忘记调用函数了...
我们看看内置的 len() 函数,怎么获取hello的长度
emmm,我们的 getStrLen() 也太特么的不好用了
放弃吧!我们还是老老实实的用内置函数吧
本章到此完结撒花!!!🎉
嘿嘿,开玩笑的。
我们再看上面函数的基本格式里就有一个“参数列表”部分
接下来,我们将使用 传参 来完善我们的 getStrLen() 函数
0x03 参数传递
我们定义需要传入参数的函数的基本格式如下:
def 一个需要传参的函数(参数名1, 参数名2):
pass # 空语句
我们调用需要传参函数需要再括号中填入参数:
一个需要传参的函数(参数1, 参数2)
参数是从左往右一次传递的。
也可以这样传参
一个需要传参的函数(参数名1=参数1, 参数名2=参数2) #与上面的传参方式等价
在函数中使用参数只需要想访问变量那样就可以
我们不妨大胆一些,不传入任何参数
额....
在需要参数的函数中,不传入足够的参数,python就会一言不合的报错....
既然如此,我们是时候完善我们的 getStrLen() 函数了。
太棒了
我在看看python内置的 len() 函数 ,len() 并非是直接打印,而是返回一个值。
这个值可以用来给变量赋值,也可以直接打印。
我们如果想要实现这个功能就需要用的函数返回值
0x04.函数返回值
我现在才说函数返回值可能有点晚了,不过影响不大
我们在前面的函数基本格式里有出现过
现在我们在回顾一下
def func1():
return 1 # 放回一个可以不用那么麻烦
def func2():
return 1, 2 # 返回一个元组
def func3():
return [1, 2, 3] # 返回一个列表
函数返回值也没有那么难
我们现在也可以改进一下刚才的函数了
def getStrLen(s): # 这里使用小驼峰命名法
l = 0 # 字符串长度变量
for _ in s: # _ 表示没有遍历变量,省略这个
l += 1 # 累加长度
return l # 返回长度
l = getStrLen("Hello World")
print(l)
我们在这段代码里只改了一行: return l
哈哈,也没有那么难的
0x05 再看参数传递
我们在前面已经大概的讲了一下参数传递,但是参数传递不止前面的那么简短。
这里就拎出来仔细讲一下
以下是调用函数时可使用的正式参数类型:
- 必备参数
- 关键字参数
- 默认参数
- 不定长参数
emmm....看起来很复杂的样子
必备参数
必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
调用 test() 函数,你必须传入一个参数,不然会出现语法错误:
def test(a):
pass
关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
以下实例在函数 test() 调用时使用参数名:
def test(a):
pass
test(a=None)
emmm....迄今为止,上面的传参方式,我们前面都用过
默认参数
调用函数时,默认参数的值如果没有传入,则被认为是默认值。下例会打印默认的age,如果age没有被传入:
def test(a=1):
print(a)
test() # 没有传入参数a的值,使用默认值
test(2) # 参数a的值为2
不定长参数
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。基本语法如下:
def functionname([formal_args,] *var_args_tuple):
function_suite return [expression]
加了星号(*)的变量名会存放所有未命名的变量参数。不定长参数实例如下:
def test(*a):
print(a)
test(1, 2, 3)
可以看到参数a就是一个元组
加了双星号(**)的变量名会存放所有命名的变量参数
def test(**a):
print(a)
test(b=1, c=2, d=3)
可以看到参数a在里面就是一个字典。
我们对函数的讲解也就告一段落了
Ⅱ.pass
0x00 什么是pass
简单而言,pass 是一种空操作(null operation),解释器执行到它的时候,除了检查语法是否合法,什么也不做就直接跳过。
它跟 return、break、continue 和 yield 之类的非空操作相比,最大的区别是它不会改变程序的执行顺序。它就像我们写的注释,除了占用一行代码行,不会对所处的作用域产生任何影响。
0x01 pass的使用
pass没有任何作用,因为定义一个空循环体,分支结构,函数都是不合法的。
所以这时候pass的作用就出现了。
pass就可以作为一个空语句来避免这类的语法报错
for _ in _:
pass
while True:
pass
def a():
pass
if _:
pass
pass的作用也就只有这些了。
Ⅲ.lambda匿名函数
0x00 什么是匿名函数
在Python中有两种函数,一种是def定义的函数,另一种是lambda函数,也就是大家常说的匿名函数。
在Python中,匿名函数是没有定义名称的函数。
虽然def在Python中使用关键字定义了普通函数,但使用关键字定义了匿名函数lambda。
因此,匿名函数也称为lambda函数。
0x01 举个栗子
计算一个数的平方,我们分别使用def函数与lambd匿名函数实现
def sqrt(x):
return x*x
sqrt1 = lambda x: x*x
可以看到在这种简单的函数中lambda显然更加的合适
我们可以看出,用lambda函数首先减少了代码的冗余,其次,用lambda函数,不用费神地去命名一个函数的名字,可以快速的实现某项功能,最后,lambda函数使代码的可读性更强,程序看起来更加简洁。
0x02 lambda语法
从上面这个简单的例子,也可以看出来lambda函数的语法是唯一的,其形式如下:
lambda argument_list:expersion
语法中的argument_list是参数列表,它的结构与Python中函数(function)的参数列表是一样的,例如
a,b
a=1,b=2
*args
**kwargs
a,b=1,*args
空
....
语法中的expression是一个关于参数的表达式,表达式中出现的参数需要在argument_list中有定义,并且表达式只能是单行的。比如以下的一些合法的表达式
1
None
a+b
sum(a)
1 if a >10 else 0
......
0x03 lambda的用处
(1)直接赋给一个变量,然后再像一般函数那样调用
c=lambda x,y,z:x*y*z
c(2,3,4)
24
当然,也可以在函数后面直接传递实参
(lambda x:x**2)(3)
9
(2)将lambda函数作为参数传递给其他函数比如说结合map、filter、sorted、reduce等一些Python内置函数使用,下面举例说明。
fliter(lambda x:x%3==0,[1,2,3,4,5,6])
[3,6]
squares = map(lambda x:x**2,range(5)
print(lsit(squares))
[0,1,4,9,16]
与sorted函数结合使用,比如:创建由元组构成的列表:
a=[('b',3),('a',2),('d',4),('c',1)]
按照第一个元素排序
sorted(a,key=lambda x:x[0])
[('a',2),('b',3),('c',1),('d',4)]
按照第二个元素排序
sorted(a,key=lambda x:x[1])
[('c',1),('a',2),('b',3),('d',4)]
与reduce函数结合使用
from functools import reduce
print(reduce(lambda a,b:'{},{}'.format(a,b),[1,2,3,4,5,6,7,8,9]))
1,2,3,4,5,6,7,8,9
(3)嵌套使用将lambda函数嵌套到普通函数中,lambda函数本身做为return的值
def increment(n):
return lambda x:x+n
f=increment(4)
f(2)
6
(4)字符串联合,有默认值,也可以用x=(lambda...)这种格式
x=(lambda x='Boo',y='Too',z='Z00':x+y+z)
print(x('Foo'))
'FooTooZoo'
(5)在tkinter中定义内联的callback函数
import sys
from tkinter import Button,mainloop
x=Button(text='Press me',command=(lambda :sys.stdout.write('Hello,World\n')))
x.pack()
x.mainloop()
这段代码还是挺有意思的,希望小伙伴们可以复制粘贴运行一下哈。(6)判断字符串是否以某个字母开头有
Names = ['Anne', 'Amy', 'Bob', 'David', 'Carrie', 'Barbara', 'Zach']
B_Name= filter(lambda x: x.startswith('B'),Names)
print(B_Name)
['Bob', 'Barbara']
(7)求两个列表元素的和
a = [1,2,3,4]
b = [5,6,7,8]
print(list(map(lambda x,y:x+y, a,b)))
[6,8,10,12]
(8)求字符串每个单词的长度
sentence = "Welcome To Beijing!"
words = sentence.split()
lengths = map(lambda x:len(x),words)
print(list(lengths))
[7,2,8]
emmm,后面的我们大都还没讲到,不过没事,就当听外星语了