Python 函数
一、函数功能和特性
功能:
1. 函数是对实现对实现某一功能的代码的封装
2. 函数可以实现代码的复用,从而减少代码的重复编写
特性:
1. 函数可以接受任何数字或者任何类型的输入作为其参数
2. 函数也可以通过关键字 return 可以返回任何数字或者其他类型的结果
二、函数的定义和调用
我们通常可以对函数进行的操作有:定义函数和调用函数
1. 定义函数
定义一个函数需要几个元素:关键字 def 函数名 小括号:() 函数体
具体如下:
1 >>> def make_a_sound(): # 定义函数, 2 ... print('quack') # 函数体,同样需要缩进 3 ... 4 >>> 5 6 7 # 上面的代码中: 8 # def 是关键字 9 # make_a_sound 是函数名 10 # () 小括号里面是函数的参数,参数可以是0.但是不管函数有几个,小括号都是必须的 11 # 当然冒号也是必须的 12 # 下面的是函数体: print('quack') 这里同样需要缩进 13
2. 调用函数
调用一个不含参数的函数,接上面的例子
1 >>> make_a_sound # 调用只使用函数名,只会得到一个对象 2 <function make_a_sound at 0x7f221b73a488> 3 >>> make_a_sound() # 正确的调用方法是: 函数名加上小括号 4 quack 5 >>> 6 7 # 无论要调用的函数是否有参数,小括号都是必须的
3.定义一个含有参数的函数并且调用此函数
1 [root@localhost ~]# python3 2 Python 3.6.0 (default, Feb 6 2017, 04:32:17) 3 [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux 4 Type "help", "copyright", "credits" or "license" for more information. 5 >>> def commentery(color): 6 ... if color == 'red': 7 ... print('You input color is {}'.format(color)) 8 ... else: 9 ... print('You input color is {}'.format(color)) 10 ... 11 >>> commentery('red') 12 You input color is red 13 >>> commentery('blue') 14 You input color is blue 15 >>>
4. 定义一个有返回值的函数并调用此函数
1 >>> def echo(anything): 2 ... return anything + ' ' + anything # 用关键字 return 定义函数的返回 3 ... 4 >>> echo('result') 5 'result result' # 函数返回值 6 >>> 7 8 # 函数可以返回任何数量(包括 0)的任何类型的结果 9 # 当一个函数没有显示的调用 return函数时,默认会返回 None 10 >>> def do_nothing(): 11 ... print('ok') 12 ... 13 >>> print(do_nothing()) 14 ok # 函数体本身执行结果 15 None # 函数自身返回值 16 >>>
5. 关于 None
None 在Python中是一个特殊的值,有重要作用。虽然None作为布尔值和 False 是一样的,但它同时又和 False 又有很多差别。
下面是一个例子
>>> thing = None >>> if thing is None: # 为了区分 None 和 False 的区别,这里使用 is ... print("It's nothing") ... else: ... print("It's something") ... It's nothing >>>
这看起来是一个微妙的差别,但对于Python 来说是很重要的。
你需要把 None he 不含任何值的空数据结构区分开来。
比如: 0(数字零)值的整型/浮点型、空字符串、空列表、空元组、空字典、空集合在Python中都等价于False,但是不等于 None
再来看下面这个函数,用于测试验证上面的观点
1 >>> def is_none(thing): 2 ... if thing is None: 3 ... print("It's None") 4 ... elif thing: 5 ... print("It's True") 6 ... else: 7 ... print("It's False") 8 ... 9 >>> is_none(None) 10 It's None 11 >>> is_none(True) 12 It's True 13 >>> is_none(0) 14 It's False 15 >>> is_none(0.00) 16 It's False 17 >>> is_none('') 18 It's False 19 >>> is_none([]) 20 It's False 21 >>> is_none(()) 22 It's False 23 >>> is_none({}) 24 It's False 25 >>> is_none(set()) 26 It's False 27 >>> is_none(' ') # 这个值得注意,这里是含有一个空格的字符串 28 It's True 29 >>>
三、函数的参数之位置参数 --》从形参角度
什么是形参:
对于函数来说,形式参数简称形参,是指在定义函数时,定义的一个变量名;
下面的代码中,arg1、arg2、arg3就是形参
什么是实参:
对于函数来说,实际参数简称实参,是指在调用函数时传入的实际的数据,是给形参赋值的,可以理解为变量的值;
下面的代码中,1、3、2 就叫实参
>>> def location_args(arg1,arg2,arg3): ... print('The first argument is ',arg1) ... print('The second argument is ',arg2) ... print('The third argument is ',arg3) ... >>> location_args(1,3,2) The first argument is 1 The second argument is 3 The third argument is 2 >>>
位置参数有一个缺点,就是你需要事先知道每个位置参数的含义,否则就会在传参数时,出现类似把第三个位置参数的值传给了第二个位置的形参
四、函数参数之默认参数 ---》 从形参角度
1 >>> def default_args(arg1,arg2,arg3=5): 2 ... print('The first argument is ',arg1) 3 ... print('The second argument is ',arg2) 4 ... print('The third argument is ',arg3) 5 ... 6 >>> default_args(1,2) 7 The first argument is 1 8 The second argument is 2 9 The third argument is 5 10 >>> default_args(1,2,3) 11 The first argument is 1 12 The second argument is 2 13 The third argument is 3 14 >>> default_args(1,2,arg3=3) 15 The first argument is 1 16 The second argument is 2 17 The third argument is 3 18 >>> default_args(1,arg2=5,arg3=3) 19 The first argument is 1 20 The second argument is 5 21 The third argument is 3 22 >>> 23 24 # 默认参数是在定义函数时定义的,必须放在位置参数的后面,否则会报错: 25 >>> def default_args(arg1,arg3=5,arg2): 26 ... print('The first argument is ',arg1) 27 ... print('The second argument is ',arg2) 28 ... print('The third argument is ',arg3) 29 ... 30 File "<stdin>", line 1 31 SyntaxError: non-default argument follows default argument 32 >>>
五、函数之动态参数 ---》从形参角度
1. 用 * 收集位置参数
>>> def print_args(*args): ... print('Return positional argument tuple:',args) ... # 一般的执行方式 >>> print_args(11,22,33,'a','b','c') Return positional argument tuple: (11, 22, 33, 'a', 'b', 'c') >>> print_args() Return positional argument tuple: () >>> list = ['a','b','c',1,2,3] >>> print_args(list) Return positional argument tuple: (['a', 'b', 'c', 1, 2, 3],) # 上面的这种方式是把每一个实参的对象作为元组的每一个元素传给函数的 # 另一种执行方式 >>> print_args(*list) Return positional argument tuple: ('a', 'b', 'c', 1, 2, 3) >>> print_args(*'abc') Return positional argument tuple: ('a', 'b', 'c') >>> # 可以看出上面的执行方式是,把一个可迭代的实参对象中的每个元素作为元组的每一个元素传给函数的
2. 用 ** 收集关键字参数
1 >>> def print_args(**kwargs): 2 ... print('keyword arguments:',kwargs) 3 ... 4 # 一般执行方式 5 >>> print_args(Monday='星期一',Tuesday='星期二',Thursday='星期三') 6 keyword arguments: {'Monday': '星期一', 'Tuesday': '星期二', 'Thursday': '星期三'} 7 >>> list = ['a', 'b', 'c', 1, 2, 3] 8 >>> dict = {'Monday': '星期一', 'Tuesday': '星期二', 'Thursday': '星期三'} 9 >>> print_args(l = list) 10 keyword arguments: {'l': ['a', 'b', 'c', 1, 2, 3]} 11 >>> print_args(dict1=dict) 12 keyword arguments: {'dict1': {'Monday': '星期一', 'Tuesday': '星期二', 'Thursday': '星期三'}} 13 # 可以看出在传参时使用关键字参数,在函数内部会是一个字典 14 15 # 另一种执行方式 16 >>> print_args(**list) 17 Traceback (most recent call last): 18 File "<stdin>", line 1, in <module> 19 TypeError: print_args() argument after ** must be a mapping, not list 20 >>> print_args(**dict) 21 keyword arguments: {'Monday': '星期一', 'Tuesday': '星期二', 'Thursday': '星期三'} 22 # 这个用法同上面的道理一样,只是这里不能接受列表,仅限于字典
六、函数参数的传递 ---》 从实参角度
从函数参数的传递方式来分,函数的参数可以分为两种:位置参数和关键字参数
1. 位置参数
2. 关键字参数
>>> def appoint_args(arg1,arg2,arg3):
... print('The first argument is ',arg1)
... print('The second argument is ',arg2)
... print('The third argument is ',arg3)
...
>>> appoint_args(arg3=3,arg2=2,arg1=1)
The first argument is 1
The second argument is 2
The third argument is 3
>>>
# 可以看出指定关键字参数,是对于传参来说的,传参时明确的用关键字形参的名称对应
# 形参的值;
# 这样就可以在传参时,不用关心传参时实参的位置了
七、函数参数总结
函数参数从形参角度来说,就是在定义函数时定义的变量名的参数,分为三种:
1. 位置参数 如: arg1,arg2
所用的参数是有位置的特性的,位置是固定的,传参时的值也是要一一对应的
2. 默认参数参数 如:arg = 5
3. 动态参数 如: *args,**kwargs
函数参数从实参角度来说,就是在调用函数时给函数传入的实际的值,分为两种
1. 位置参数
在传参时,值和定义好的形参有一一对应的关系
2. 关键字参数
在传参时,利用key = value 的方式传参,没有对位置的要求
八、函数中的文档字符串
程序的可读性很重要,在函数的开始部分附上关于此函数的说明文档是个很好的习惯,这就是函数的文档字符串
1 >>> def echo(anything): 2 ... 'echo return its input argument' # 定义简单的一行说明文字 3 ... return anything 4 ... 5 >>> help(echo) # 调用 help() 函数时,把函数名作为参数传递,就会打印出说明文档,按 q 键即可退出 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Help on function echo in module __main__: 21 22 echo(anything) 23 echo return its input argument 24 (END) 25 26 # 当然我们同样可以用 """ 多行字符说明文档""" 的形式添加多行说明文档,而且更规范 27 >>> def print_if_true(thing,check): 28 ... ''' 29 ... Prints the first argument if a second argument is true. 30 ... The operattion is: 31 ... 1. Check whether the *second* argument is true. 32 ... 2. If it is, print the *first* argument. 33 ... ''' 34 ... if check: 35 ... print(thing) 36 ... 37 >>> help(print_if_true) 38 39 # 仅打印说明文档后立即退出,可以使用如下方法: 40 >>> print(echo.__doc__) 41 echo return its input argument 42 >>> print(print_if_true.__doc__) 43 44 Prints the first argument if a second argument is true. 45 The operattion is: 46 1. Check whether the *second* argument is true. 47 2. If it is, print the *first* argument. 48 49 >>>
九、匿名函数:lambda() 和三元运算
lambda函数是用一个语句表达的匿名函数,可以用它来代替小的函数。
# 先看一个简单的普通函数 >>> def f1(arg1,arg2): ... return arg1 + arg2 ... >>> f1(2,5) 7 # 再看 lambda 表达式 # 格式: # lambda 参数:函数体 >>> lambda arg1,arg2:arg1 + arg2 <function <lambda> at 0x7f3fe4120510> >>> sum_number = lambda arg1,arg2:arg1 + arg2 >>> sum_number(2,5) 7 >>>
三元运算就是用来写简单的 if ... eles: ...语句的
基本语法:
条件为真时的表达式 /结果 if 条件 else 条件为假时的表达式/结果
# 普通的if else >>> def max(arg1,arg2): ... if arg1 > arg2: ... print('Max is:',arg1) ... else:print('Max is:',arg2) ... >>> max(3,4) Max is: 4 # 三元运算 >>> def max2(arg1,arg2): ... print('Max is:',arg1) if arg1 > arg2 else ('Max is:',arg2) ... >>> max2(3,5) Max is: 5 >>>
>>> x = 3 if (y == 1) else 2
# 上面这个表达式的意思就是:如果y等于那么就把3赋值给x,否则把2赋值给x, 条件中的括号是可选的,为了可读性可以考虑加上去.if else中的表达式可以是任何类型的,既可以函数,还可以类
>>> (func1 if y == 1 else func2)(arg1, arg2)
# 如果y等于1,那么调用func1(arg1,arg2)否则调用func2(arg1,arg2)
>>> x = (class1 if y == 1 else class2)(arg1, arg2)
# class1,class2是两个类
扩展知识:Python 发送邮件
import smtplib from email.mime.text import MIMEText from email.utils import formataddr msg = MIMEText('邮件内容', 'plain', 'utf-8') msg['From'] = formataddr(["西瓜甜",'dockerhub@163.com']) msg['To'] = formataddr(["走人",'86000153@qq.com']) msg['Subject'] = "主题-测试" server = smtplib.SMTP("smtp.126.com", 25) server.login("dockerhub@163.com", "邮箱密码") server.sendmail('dockerhub163.com', ['86000153@qq.com',], msg.as_string()) server.quit()