Python程序设计5——函数
本章介绍Python中模块和函数的概念。
Python程序是由包、模块和函数三者组成,包是由一系列模块组成的集合,模块是处理某一类问题的函数和类的集合。Python提供的许多工具包和模块安装在Python的安装目录下的lib子目录中。例如,在Python安装目录下lib目录下,有一个sqlite3文件夹,该文件夹就是一个包,这个包用于完成连接sqlite3数据库的基本操作。在sqlite3文件夹下有一个test的子包,还有一个_init_.py文件,该文件是sqlite3包的注册文件,如果没有该文件,Python将不能识别sqlite3包。包必须至少包含一个_init_.py文件,该文件的内容可以为空。_init_.py用于标识当前文件夹是一个包。
1 函数
对于一个函数来说,包括三个方面,函数的定义、函数的调用和函数的执行,函数的定义使用def来定义一个函数,光有函数的定义是不行的,函数还必须得到有效的调用,否则这个函数是没有用的,调用函数后,系统就会一条条执行函数的语句。
1.1 函数的定义
函数定义非常简单,使用保留字def声明即可,在定义函数时候需要定义返回值类型.语法如下:
def function_name(参数列表):
statement
[return value]
例如:
def hello():
print 'Hello World'
python允许返回多个参数,但是本质上还是只有一个参数,只是将这些参数进行了打包,以元组、列表形式返回。
其中,返回值不少必须的,如果没有return语句,则Python默认返回值为None。注意函数列表后面有一个冒号,和循环语句一样。
下面定义一个函数
def login(username, password):
if(username == 'admin') and (password == 'admin'):
print 'login succeed'
else:
print 'login failed'
username = raw_input('Please enter your name:')
password = raw_input('Please enter your password:')
login(username, password)
1.2 函数形参与默认参数值
参数的传递有两种方式:值传递和引用传递。无论是实际参数还是形式参数在函数定义的圆括号内指定,用逗号隔开,当调用函数的时候,也需要用同样的方式提供值。形参是函数定义时候,在函数签名里面的,调用时候赋予函数调用时的值叫实参。Python通过名字绑定机制,把实际参数的值和形式参数的值绑定在一起,即把形式参数传递到函数所在的局部命名空间中,形式参数和实际参数指向内存中的同一个存储空间。
1.默认参数值
函数的参数支持默认值。当某个参数没有传递实际值时,函数将使用默认参数计算,例如可以向login()函数的username参数和password参数分别提供一个默认值。
def login(username = 'aq', password = 'aq'):
if(username == 'admin') and (password == 'admin'):
print 'login succeed'
else:
print 'login failed'
#提供几个参数
login('admin', 'admin')
login('admin')
login(password = 'admin')
login()
运行结果:
login succeed
login failed
login failed
login failed
分析:第一次调用时候,分别提供了两个实际参数,这两个参数会覆盖掉定义函数时候提供的默认值。也就是username和password的值均为admin,因此符合条件,可以通过。第二次调用时候只提供了一个参数,这个参数会被当作提供给第一个形参,也就是username值为admin,而password依然采用默认值,也就是aq,因此不通过。第三次调用时候提供了password的实参,但username依然采用默认的,所以不通过。第四次调用没有提供参数,所以都采用默认值,因此也不会通过。
2.列表作形参
参数可以是变量,也可以是元组、列表等内置数据结构,例如:
def login(usernames = [], password = "admin"):
username = usernames[0]
if(username == 'admin') and (password == 'admin'):
print 'Login success'
else:
print 'Login failed'
login(['admin', 'aq'])
输出结果:Login success
3.可变长度参数值
在程序开发中,常常需要传递可变长度的参数。在函数的参数前使用标识符*,可以实现这个要求,*可以引用元组,将多个参数组合在一个元组中。
def login(*userpwds):
username = userpwds[0]
password = userpwds[1]
if(username == 'admin') and (password == 'admin'):
print 'Login success'
else:
print 'Login failed'
login('admin','admin')
运行结果:Login success
在该函数中,用*标识符定义了可变长度的参数userpwds,通过它可以引用一个元组,并索引参数进行赋值。
4.字典作形参
Python还提供了另一个标识符**,在形式参数前面加上**,可以引用一个字典作为参数。下面这段代码实现了在一个字典中匹配元组的元素。
#传递字典类型的参数 def login(**userpwds):
keys = userpwds.keys()
username = ''
password = ''
for key in userpwds:
if 'username' == key:
username = userpwds[key]
if 'password' == key:
password = userpwds[key]
if(username == 'admin') and (password == 'admin'):
print 'Login success'
else:
print 'Login failed'
login(username = 'admin',password = 'admin')
在该段代码中,定义了login函数的参数为字典类型,形参是**userpwds与实际参数username='admin'、password='admin'对应,生成一个结构为{username:'admin',password:'admin'}的字典。
注意:如果函数的参数类型既有元组(形式参数前加*),又有字典(形式参数前加**),那么*必须写在**的前面,也就是元组形参必须在字典形参前面。
使用实例:
下面这个程序实现了对用户名称检验、是否是数字以及号码位数进行校验。
def registerUser(username = 'py', idcard = 'python', tel = ''):
userName = raw_input('Please input username: ')
#check length of username
if(len(userName) > 3 and len(userName) < 20):
idcard = raw_input('Please input your account: ')
if(idcard.isdigit()):
tel = raw_input('Please input your telephone number: ')
if(tel.isdigit() and (7 < len(tel) < 20)):
print 'congratulations!regeister success!'
else:
print 'Tel format is wrong!'
else:
print 'Account format is wrong!' else:
print 'length of username shoud be between 3 and 20'
print userName,idcard,tel
registerUser()
输出结果:
Please input username: erseresd
Please input your account: 23234234234
Please input your telephone number: 22432432
congratulations!regeister success!
erseresd 23234234234 22432432
1.3 函数的调用
python进行函数调用时候传递参数两种形式,一种是标准调用,这种调用方式和其他语言比如C、Java没有什么区别,一种是python特有的关键字赋值方式。
假定现在有一个函数
def hello():
print 'Hello World'
进行调用的时候,一种是标准的,比如:
net_conn('www.python.org','8080')
另一种就是关键字赋值
net_conn(host = 'www.python.org',port = 8080)
1.4 函数的返回值
使用return语句来返回需要的值。
def login(username,password):
msg = ''
if(username == 'admin') and (password == 'admin'):
msg = 'Login Successfully'
else:
msg = 'Login Failed'
return msg
print login('admin','admin')
输出结果:Login Successfully
上面使用了print函数将返回值输出,如果只使用return语句返回,系统将不会输出。
如果需要返回多个值,可以将需要返回的值全部打包到元组中,调用时,对返回的元组解包即可。
def operat(x,y,z):
x = x + 5
y = y + 5
z = z + 5
oper = [x,y,z]
numbers = tuple(oper)
return numbers
x,y,z = operat(1,2,3)
print x,y,z
输出结果:6,7,8
2 模块
Python程序由一个个模块组成,一个Python文件就是一个模块。
2.1 模块的创建
模块是把一组相关的函数或代码组织到一个文件中,即一个文件就是一个模块。模块由代码、类和函数组成,其中类和函数可以有0个或多个。例如创建一个myFirstModule.py文件,即定义了一个名称未myFirstModule的模块,在该模块中定义两个函数和一个类,并在该类中定义一个方法。
在编辑Python程序时,当使用import关键字导入一个模块时,系统首先会查找当前路径,然后查找lib目录、site-packages目录和环境变量PYTHON PATH设置的目录。
实例应用:
第一个模块
'''
Created on 2013-8-5 @author: Landau
''' class Person:
def addPer(self):
userName = raw_input('Please enter your name:')
print userName
if userName != '':
print 'person add success'
else:
print 'person add failed'
另一个模块:
'''
Created on 2013-8-5 @author: Landau
'''
import addPerson
person = addPerson.Person()
person.addPer() 运行测试:
Please enter your name:ew
ew
person add success
2.2 模块的导入
如前所述,模块的导入需要使用import语句,模块导入的格式如下:
import 模块名
也可以直接导入所需要的函数名
import 模块名.函数名
这种方式比较麻烦,每次调用模块中的函数或类时,都需要使用模块名作为前缀来调用。为了解决这个问题,Python提供了from...import语句可以讲模块中的类或函数导入,从而不需要使用模块名作为前缀。语法如下
from 模块名 import 函数名或者from 模块名 import *
2.3 模块属性
模块有一些内置的属性,用于完成特定的任务。
python中每个模块都有一些特定的属性,用于完成某项任务。下面介绍最常用的两个模块属性:_name_和_doc_
1.__name__属性
__name__属性用于判断当前模块是不是程序的入口,如果当前程序正在被使用,__name__的值为__main__。在编写程序时候,通常需要给每个模块添加条件语句,用于单独测试该模块的功能,例如创建一个模块myThirdModule
if __name__ == '__main__':
print 'myThirdModule is main module'
else:
print 'myThirdModule is called by another module'
运行结果:myThirdModule is main module
注意:__name__的name两边各有两个下划线,不是_name_
2.__doc__属性
Python中的模块是一个对象,每个对象都有__doc__属性,该属性用于描述该对象的作用,下面创建另一个模块call_myThirdModule,这个模块很简单,只需要导入myThirdModule
'''
Created on 2013-8-5 @author: Landau
'''
import phone_number
print __doc__
运行结果:
myThirdModule is called by another module Created on 2013-8-5 @author: Landau
属性__doc__可以输出文档字符串的内容。
'''
Created on 2013-8-5 @author: Landau
''' class MyClass:
'one String'
def printHello(self):
'print hello world'
print 'HELLO WORLD'
print MyClass.__doc__
print MyClass.printHello.__doc__
输出结果:
one String
print hello world
可以看到__doc__提取了程序的字符串属性
2.4 模块的内置函数
在buildin模块中定义了许多在软件开发过程中经常用到的函数,利用这些函数可以实现数据类型的转换、数据的计算、序列的处理等功能。下面介绍内联模块中常用的函数。
1.apply()函数
apply()函数可以实现调用可变参数列表的功能,把函数的参数放到一个元组或序列中。apply()函数的语法格式如下:
apply(function_name[,argslist])
该函数有三个参数:
function_name:该参数是必须的,表示自定义函数的名称
args:该参数是可选的,它是一个包含了自定义函数参数的列表和元组,如果不指定该参数,则表示被执行的函数没有任何参数
kwargs:该参数可选,它是一个字典类型的参数,字典中key值为函数的参数名称,value为实际参数的值。
def login(userName, password):
msg = ''
if(userName == 'admin') and (password == 'admin'):
msg = 'Login Successfully'
return msg
else:
msg = 'Login Failed'
return msg
print apply(login, ('admin', 'admin'))
运行结果:Login Successfully
apply函数的元组参数是有序的,本例中,元素的顺序必须与login函数的形式参数顺序一致。
2.filter函数
filter函数可以对序列做过滤处理,简单的说就是用函数来过滤一个序列,把序列的每一项传递到过滤函数。对自定义函数的参数返回的结果是否为True做过滤,并一次性返回处理结果,如果过滤函数返回的结果为False,那么该元素将从列表中删除该项。filter函数语法格式如下:
filter(function_name,sequence)
filter函数有两个参数,其中:
function_name是必须的,是自定义函数,在函数function_name中定义过滤规则,如果function_name函数的返回值为None,则表示sequence序列中的每一项都为True,从而返回左右的序列元素。
sequence:必须的,表示要过滤的序列
filter函数的返回值由function_name函数的返回值决定,该函数返回所有为True的过滤项组成的序列,返回值的类型与参数sequence类型相同。例如参数sequence的类型为元组,那么返回值类型也是元组,下面介绍filter函数使用方法:
def validate(usernames):
if (len(usernames) > 4) and (len(usernames) < 20):
return usernames
print filter(validate, ('admin','hello', 'hel','ddfdlj'))
输出结果:('admin', 'hello', 'ddfdlj')
3.reduce函数
reduce函数可以实现连续处理功能,例如,对某个序列中的元素进行累加操作,语法格式如下:
reduce(function_name,sequence)
下面看一个连续相乘的例子:
def operat(x,y):
return x*y
print reduce(operat, (1,2,3,4,5,6))
print reduce(operat, (2,3,4), 5)
输出结果:
720
120
4.map函数
map函数可以对多个序列中的每个元素执行相同的操作,并返回一个与输入序列长度相同的列表。
map(function_name, sequence[,sequence,....])
序列的长度可以不一样,系统会自动给短序列后面补None
def add1(a):
return a + 1
def add2(a, b):
return a + b
def add3(a, b, c):
return a + b + c
a1 = [1, 2, 3, 4, 5]
a2 = [1, 2, 3, 4, 5]
a3 = [1, 2, 3, 4, 5] b = map(add1, a1)
print b c = map(add2, a1, a2)
print c d = map(add3, a1, a2, a3)
print d
输出结果:
[2, 3, 4, 5, 6]
[2, 4, 6, 8, 10]
[3, 6, 9, 12, 15]
注意:如果map提供了多个序列,则每个序列中的元素一一进行处理,然后将处理后的元素再组成一个序列
Python程序设计5——函数的更多相关文章
- Python‘ssl.match_hostname()’函数SSL证书验证安全绕过漏洞
漏洞名称: Python‘ssl.match_hostname()’函数SSL证书验证安全绕过漏洞 CNNVD编号: CNNVD-201312-033 发布时间: 2013-12-04 更新时间: 2 ...
- Day3 - Python基础3 函数、递归、内置函数
Python之路,Day3 - Python基础3 本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8. ...
- Python题集:2019春Python程序设计选修课习题笔记
一.判断题: 1-1.在Python 3.x中可以使用中文作为变量名. 答案:√ 1-2.Python变量使用前必须先声明,并且一旦声明就不能再当前作用域内改变其类型. 答案:× 1-3.Python ...
- Python学习笔记-函数基础
函数基础 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 为什么使用函数:减少重复代码.使程序变的可扩展使程序变得易维护 1.定义一个函数 #定 ...
- Python全栈开发之路 【第四篇】:Python基础之函数
本节内容 函数def: 1.位置参数,默认参数 2.位置参数,关键参数 3.如果参数中出现 *users,传递的参数就可以不再是固定的个数, 传过来的所有元素进行打包成元组 *args,**kwarg ...
- Python基础3 函数、递归、内置函数
本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 温故知新 1. 集合 主要作用: 去重 关系测 ...
- Python自动化开发 - 函数
本节内容 函数背景介绍 函数是什么 参数与局部变量 返回值 递归函数 匿名函数 函数式编程介绍 高阶函数 一.函数背景介绍 老板让你写一个监控程序,监控服务器的系统状况,当cpu/memory/dis ...
- 《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 2 章 答案
判断对错1.编写程序的好方法是立即键入一些代码,然后调试它,直到它工作.2.可以在不使用编程语言的情况下编写算法.3.程序在写入和调试后不再需要修改.4.Python 标识符必须以字母或下划线开头.5 ...
- python程序设计——基本语言特性
参考<Python程序设计(第2版)> 清华大学出版社 董付国 ##### 除特殊说明外,以下代码示例,均为python 3.6版本 ##### 一.Python语言特性 1.python ...
随机推荐
- linux C gbk utf-8编码转换
http://blog.csdn.net/sealyao/article/details/5043138
- RedHat 6.8 内核编译
/*************************************************************************** * RedHat 6.8 内核编译 * 说明: ...
- tensorflow 学习笔记-1
http://www.jianshu.com/p/e112012a4b2d 参考的网站 -------------------------------------------------------- ...
- 前端调错看ajax请求操作
---------------------------------------------------------------------------------------------------- ...
- Mycat 在vscode中的开发配置
mycat是国产目前最被追捧的一款分布式数据库集群软件,有一些公司对数据库和应用都有自己的集群方案,但是更多的是一些面对庞大的数据量,而束手无策. 对于这种问题,我想百分之80遇到的是数据库的瓶颈,所 ...
- BZOJ4355: Play with sequence
BZOJ4355: Play with sequence https://lydsy.com/JudgeOnline/problem.php?id=4355 分析: 模板题. 把\(2\)操作看成先区 ...
- RabbitMQ 权限分离&HA操作文档
概要 默认情况下,使用帐号guest帐号登陆MQ,所有用户的queue信息,全部创建在根目录/的virtual host下,而这样,就会导致,任一用户登录后,都能看到其他用户的queue信息. 针对以 ...
- python模块导入的问题
从模块导入函数时,通常可以使用 import somemodule 或者 from somemodule import somefunction 或者 from somemodule import s ...
- WPF中DataGrid控件的过滤(Filter)性能分析及优化
DataGrid控件是一个列表控件, 可以进行过滤,排序等.本文主要针对DataGrid的过滤功能进行分析, 并提供优化方案. 1)DataGrid的过滤过程: 用户输入过滤条件 ...
- webrtc自带client的视频引擎创建代码走读
src\webrtc\examples\peerconnection\client\conductor.ccbool Conductor::InitializePeerConnection()1 we ...