python 第四章 函数

时间:2023-01-01 11:48:45

函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。

定义一个函数

你可以定义一个由自己想要功能的函数,以下是简单的规则:

  函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()

  任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。

  函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。

  函数内容以冒号起始,并且缩进。return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 def name():
5     print("xing")
6 
7 name()
8 #输出
9 xing

给函数传递参数

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 def name(username):
5     print("x"+username)
6 
7 name("yx")
8 #输出
9 xyx

实参和形参

在函数name()的定义中,变量username是一个形参——函数完成其工作所需的一项信息。在代码name("yx")中,值"yx"是一个实参,实参是调用函数时传递

给函数的信息。我们调用函数时,将要让函数使用的信息放在括号内。在name(username)中,将实参"yingxu",传递给了函数name(),这个值被储存在username中

传递实参
位置参数
调用函数时,必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此
最简单的关联方式是基于实参的顺序,这种关联方式被称为位置实参。
使用位置实参来调用函数时,如果实参的顺序不正确,结果可能出乎意料

关键字实参
关键字实参是传递给函数的名称—值对。你直接在实参中将名称和值关联起来了,
因此向函数传递实参时不会混淆。关键字实参让你无需考率函数调用中的实参顺序,还可以清楚的指出函数调用中各个值的用途
比如 name(username="值")

默认值
使用默认值时,在形参列表中必须先列出没有默认值的形参,在列出有默认值的实参。这让python依然能够正确的解读位置实参

避免实参错误
如果开始使用函数后,如果遇到实参不匹配错误,应该是提供的实参多于或者少于
函数完成其工作所需的信息,将出现实参不匹配的错误

位置实参和任意数量实参
如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后

global关键字 nonlocal关键字

整个模块的变量都是全局变量 可用于整个模块,可以在函数内部读取他,最好不要在函数内修改他。如果真的要改 可以用 "global"关键字。修改嵌套作用域中的变量:如果在内部函数外部函数的局部变量就要使用nonlocal关键字了

使用global关键字修饰的变量之前可以并不存在,而使用nonlocal关键字修饰的变量在嵌套作用域中必须已经存在

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 x = 99
 5 def func():
 6     x = 88
 7 func()
 8 print(x) 
 9 #输出99
10 
11 x = 99
12 def func()
13     global x
14     x = 88
15 func()
16 print(x)    
17 #输出88
18 
19 def func():
20     count = 1
21     def foo():
22         count = 12
23     foo()
24     print(count)
25 func()
26 #输出1
27 
28 def func():
29     count = 1
30     def foo():
31         nonlocal count
32         count = 12
33     foo()
34     print(count)
35 func()
36 #输出12

lambda表达式 又叫匿名函数

python写一些执行脚本时,使用lambda就可以省下定义函数过程,比如说我们只是需要写个简单的脚本来管理服务器时间,我们就不需要专门定义一个函数然后在写调用,使用lambda就可以使的代码更加精简。
对于一些比较抽象并且整个程序执行下来只需要调用一两次的函数,有时候给函数起个名字也是比较头疼的问题,使用lambda就不需要考虑命名的问题了。
简化代码的可读性。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 """lambda 格式"""
 5 #lambda 形参名:处理逻辑
 6 #v = lambda 形参名:处理逻辑  #赋值给一个变量
 7 #print(v(形参名的值))
 8 
 9 lambda x,y,z:(x+1,y+1,z+1)
10 v = lambda x,y,z:(x+1,y+1,z+1)
11 print(v(1,2,3))
12 #输出
13 (2, 3, 4)
14 
15 lambda x:x+1
16 v = lambda x:x+1
17 print(v(10))
18 #输出
19 11
20 
21 lambda name:name+"_sb"
22 v = lambda name:name+"_sb"
23 print(v("alex"))
24 #输出
25 alex_sb

filter 函数(过滤器)  

该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 v=list(filter(lambda x:x%2,range(10)))
5 print(v)
6 #输出
7 [1, 3, 5, 7, 9]
8 """list(filter(函数,逻辑处理,列表))  过滤后结果转换成列表
9 不一定要是列表,只要是可迭代对象都可以"""

map() 函数(映射)

函数逻辑处理如果简单可以用lamdba
否则自定义一个函数最好。

1 map(function, iterable, ...) #unction -- 函数,有两个参数 iterable -- 一个或多个序列

第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

 1 #!/usr/bin/env python
 2 # -*- coding:utf8 -*-
 3 
 4 >>>def square(x) :            # 计算平方数
 5 ...     return x ** 2
 6 ... 
 7 >>> list(map(square, [1,2,3,4,5]))   # 计算列表各个元素的平方
 8 [1, 4, 9, 16, 25]
 9 
10 >>> list(map(lambda x: x ** 2, [1, 2, 3, 4, 5]))  # 使用 lambda 匿名函数
11 [1, 4, 9, 16, 25]
12  
13 # 提供了两个列表,对相同位置的列表数据进行相加
14 >>> list(map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10]))
15 [3, 7, 11, 15, 19]
16 """list(map(函数,逻辑处理,列表)) 结果转换成列表
17  不一定要是列表,只要是可迭代对象都可以。"""

 

reduce() 函数

对参数序列中元素进行累积

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from functools import reduce  #需要先在模块中导入redece功能
 5 v=reduce(lambda x,y:x+y,[1,2,3,4,5,6],1)
 6 print(v)
 7 #输出
 8 22
 9 """reduce(lambda 逻辑处理,列表,从什么开始)1表示从什么开始 这里表示开头x=1
10 必须是一个两个参数的函数,不一定要是列表,只要是可迭代对象就可以"""

内置函数

abs(数字) 绝对值

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 >>> a = 8
5 >>> b = -8
6 >>> abs(a)
7 8
8 >>> abs(b)
9 8

round(浮点数)  四舍五入

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 >>>a = 4.5
5 >>>b = 4.6
6 >>>round(a)
7 4
8 >>>round(b)
9 5

pow(x,y,z) 表示次方 x**y & z  两个参数表示次方 三个参数表示次方取余

#!/usr/bin/env python
# -*- coding:utf-8 -*-

>>> pow(2,3)
8
>>> pow(2,3,3)
2

divmod(x,y) 取商得余数,返回一个包含商和余数的元组(a // b, a % b)。

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 >>>divmod(7, 2)
5 (3, 1)
6 >>> divmod(8, 2)
7 (4, 0)

all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 True,如果是返回 True,否则返回 False。注意:空元组、空列表返回值为True,这里要特别注意。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 >>>all(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
 5 True
 6 >>> all(['a', 'b', '', 'd'])   # 列表list,存在一个为空的元素
 7 False
 8 >>> all([0, 1,2, 3])          # 列表list,存在一个为0的元素
 9 False
10    
11 >>> all(('a', 'b', 'c', 'd'))  # 元组tuple,元素都不为空或0
12 True
13 >>> all(('a', 'b', '', 'd'))   # 元组tuple,存在一个为空的元素
14 False
15 >>> all((0, 1, 2, 3))          # 元组tuple,存在一个为0的元素
16 False
17    
18 >>> all([])             # 空列表
19 True
20 >>> all(())             # 空元组
21 True

any()函数用于判断给定的可迭代参数 iterable 是否全部为 False,是则返回 False,如果有一个为 True,则返回 True。元素除了是 0、空、FALSE 外都算 True

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 >>>any(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
 5 True
 6  
 7 >>> any(['a', 'b', '', 'd'])   # 列表list,存在一个为空的元素
 8 True
 9  
10 >>> any([0, '', False])        # 列表list,元素全为0,'',false
11 False
12  
13 >>> any(('a', 'b', 'c', 'd'))  # 元组tuple,元素都不为空或0
14 True
15  
16 >>> any(('a', 'b', '', 'd'))   # 元组tuple,存在一个为空的元素
17 True
18  
19 >>> any((0, '', False))        # 元组tuple,元素全为0,'',false
20 False
21   
22 >>> any([]) # 空列表
23 False
24  
25 >>> any(()) # 空元组
26 False

bool() 函数用于将给定参数转换为布尔类型,如果没有参数,返回 False。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 >>>bool()
 5 False
 6 >>> bool(0)
 7 False
 8 >>> bool(1)
 9 True
10 >>> bool(2)
11 True

转换进制函数

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 >>> a = 10
 5 >>> hex(a) #十进制转十六进制
 6 '0xa'
 7 >>> oct(a) #十进制转八进制
 8 '0o12'
 9 >>> bin(a) #十进制转二进制
10 '0b1010'

转换成ascii码表中的数

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 >>> a = 78
5 >>> chr(a)  #把数字转换成ascii码表
6 'N'
7 >>> a = "N"
8 >>> ord(a)  #写一个字符对应ascii码表中的数
9 78

vars() 函数返回对象的属性和属性值的字典对象

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 >>>print(vars())
5 {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}

dir(),type(),help()

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 >>> dir(help) #打印某一个对象下面都有哪些方法
 5 ['__call__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
 6 
 7 >>> a = "a"
 8 >>> type(a)  #查看数据类型
 9 <class 'str'>
10 
11 >>> help(dir)  #查看方法即解释
12 Help on built-in function dir in module builtins:
13 
14 dir(...)
15     dir([object]) -> list of strings
16     
17     If called without an argument, return the names in the current scope.
18     Else, return an alphabetized list of names comprising (some of) the attributes
19     of the given object, and of attributes reachable from it.
20     If the object supplies a method named __dir__, it will be used; otherwise
21     the default dir() logic is used and returns:
22       for a module object: the module's attributes.
23       for a class object:  its attributes, and recursively the attributes
24         of its bases.
25       for any other object: its attributes, its class's attributes, and
26         recursively the attributes of its class's base classes.

enumerate()  可以吧一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 for i,v in enumerate(range(10)):
 5     print(i,v)
 6 #输出
 7 0 0
 8 1 1
 9 2 2
10 3 3
11 4 4
12 5 5
13 6 6
14 7 7
15 8 8
16 9 9

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 >>> l1,l2,l3 = (1,2,3),(4,5,6),(7,8,9)
 5 >>> list(zip(l1,l2,l3))
 6 [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
 7  
 8  
 9 >>> str1 = 'abc'
10 >>> str2 = 'def123'
11 >>> zip(str1,str2)
12 [('a', 'd'), ('b', 'e'), ('c', 'f')]
13 
14 #zip()方法用在for循环中,就会支持并行迭代:
15 
16 l1 = [2, 3, 4]
17 l2 = [4, 5, 6]
18 
19 for (x, y) in zip(l1, l2):
20     print(x, y, '--', x * y)
21 #输出 
22 2 4 -- 8
23 3 5 -- 15
24 4 6 -- 24

bytes() 把一个字符串转换成字节的形式,需要先定义一个变量

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 name = "你好"
 5 print(bytes(name,encoding="utf-8"))
 6 print(bytes(name,encoding="utf-8").decode("utf-8"))
 7 #输出
 8 b'\xe4\xbd\xa0\xe5\xa5\xbd'
 9 你好
10 
11 #encoding 编码
12 #decode   解码
13 #需要注意用什么格式编码就用什么格式解码 否则会报错,python3默认"utf—8

 函数编写指南
应给函数指定描述性的名称 且只在其中使用小写字母和下划线。给模块命名时也应遵守上述约定,每个函数都最好加上中文注释
给形参指定默认值时,等号两边不要有空格
函数调用中的关键字实参,也应该这样
如果程序中或模块包含多个函数,可使用两个空行将相邻的两个函数分开,这样将更容易知道前一个函数在什么地方结束,下一个函数从什么地方开始
所有import语句都应放在文件开头,唯一例外的情形是,在文件开头使用了注释来描述整个程序想