python:11:函数

第一章:python

第11节:函数

1,函数的简单表现形式:

1,用def来创建函数,如def foo():

>>> def panduan():
... ····if raw_input('please input a number:') == 1:
... ········print '1'
... ····else:
... ········print '0'
>>> panduan()

2,函数的返回值:

当函数式当中有return则函数返回值为return中的内容,函数式中没有return,则返回值为none
>>> def hello():
... ····return 'abc'
>>> y=hello()
>>> y
'abc'
函数返回值的详细解释,函数调用后默认返回None,可用return来返回值,return执行后,函数终止,返回值可以是任意类型,可以通过条件判断改变返回值;
带有用户输入(raw_input)类型的函数,应定义在调用函数的前面。

2,形参与实参

定义函数时,函数后面圆括号中的变量名称叫做“形式参数”简称形参;
调用函数时,函数后面圆括号中的变量名称叫做“实际参数”简称实参;
名为“谁是凶手”的函数应用例子,解释形参和实参的所用:
>>> def who_is(name):
... ····l=open('first_name.txt').read().strip().split('\t')
... ····for x in range(len(x)):
... ········if l[x]==name:
... ············return "%s is murder and it's number is %s"(l[x], x)
>>> n=who_is(raw_input('please input a name:'))
>>> print n
def who_is(name):当中的name是形参,而who_is(raw_input(‘please input a name:’))当中的raw_input是实参
默认参数及实际参数传值
默认参数是指函数调用时没有为参数提供值则使用预先定义的默认值;
调用函数时不进行传值,则使用默认参数,调用函数时如果进行传值,则使用实参值;
定义默认参数原则,只能自右向左定义默认参数
实例1:定义默认参数
>>> def machine(x=3, y='奶油'):
... ····print "生成一个",x , '元', y, '口味的冰激凌!'
>>> machine()
'生成一个3元奶油口味的冰激凌!'
实例2:自右向左定义参数:
>>> def machine(y, x=3):
... ····print "生成一个",x , '元', y, '口味的冰激凌!'
>>> machine(y='巧克力')
'生成一个3元巧克力口味的冰激凌!'
>>> machine(x=6, y='巧克力')

3,局部变量与全局变量

局部变量是指在函数内定义的变量,只可以在函数内使用;
全局变量可以在函数内及函数外使用;
当函数被调用时,局部变量发挥作用,如果局部变量的对应函数未被调用,则局部变量不发挥作用。局部变量发挥作用与否,与其函数是否被调用相关。

global语句,作用是可将局部变量强制声明为全局变量,但在函数内的局部变量,如果没有被调用时,则global声明为全局变量无效。
函数如果被调用,其内部定义的global变量会定义为全局变量,且会对已经定义的全局变量重新赋值。
例如:
>>> x='I am global var'
>>> def fun():
... ····global x
... ····x=100
>>> fun()
>>> print x
100

4, 元组,列表和字典对于函数的传值方法(重点)

如果函数需要两个形参,而向其传递的实参为一个包含两个元素的元组,则需要以下的传值方法
>>> def f(name, other):
... ····print "%s : %s"%(name, other)
>>> t=('name', 'other')
>>> f(*t)#列表和元组传值必须加入一个星号后面加入列表或元组名称
'name : other'
在函数调用中使用
*
**
这两个符号来指定元组和字典
*:元组
:字典
使用元组和字典的元素作为非关键字以及关键字参数的方法。
所以想函数传递元组这个实参,元组中的元素个数必须等于形参个数
如果想利用对应关系传值,就需要用到字典,但在传值过程中,字典中的键(名称),字典中键的名称必须与函数中实参的名称相同,否则传值失败
例子:
>>> def f(name='name', age=0):
... ····print "name: %s"%name
... ····print "age:%s"%age
>>> d={'age': 30, 'name': 'milo'}
>>> f(**d)#字典传值必须
加入两个星号**后面加入字典名称
name: milo
age:30
所以根据字典的特性,字典的键是唯一的,所以利用字典给函数传值时,函数中不能出现两个同名的形参
字典中键的名称可以和形参同名,但字典中键的出现顺序可以和形参的位置不对应,因为字典传值取决的是映射关系,而不是位置关系。

5, 处理多余实参(重点)

利用元组和字典来处理函数传入的多余实参
>>> def fun(*args, **kwargs)
如果函数编写形式如上,则向函数传入的多余元组或列表元素会存入args中,多余字典元素会存入kwargs中;其中*args表示元组传递,**kwargs表示字典传递,args或kwargs名称用户可以自定义,但是星号必须有。
实例:
>>> def fun(x, *args, **kwargs):
... ····print x
... ····print args
... ····print kwargs
>>> fun(1)#函数fun没有多余传值所以,args和kwargs都为空
1
()
{}
>>> fun(1, 2, 3, 4, 5)#函数fun的传值形式是元组传值方式,多余了4个传值,所以args这个元组包含4个元素
1
(2, 3, 4, 5)
{}
>>> fun(x=1, y=2)#函数fun的传值时一种映射关系传值,x=1是函数正常传值,而y=2是多余传值,鉴于这种y=2的映射关系,所以将这个多余的传值存入了kwargs字典对象中
1
()
{'y': 2}
注意:
>>> fun(1, 2, 3, 4, 5, x=10, y=20, z=30)
Traceback
TypeError : f() got multiple values for keyword argument 'x'
在这种传值过程中,实参1和x=10存在冲突,所以函数不能明确形参x具体传递哪个值
正确的写法应该是:
>>> fun(1, 2, 3, 4, 5, y=20, z=30)
1
(2, 3, 4, 5)
{'y': 20, 'z': 30}

6,匿名函数lambda

lambda语句中,冒号前是参数,可以有多个,用逗号隔开,冒号右边为返回值,不用写return语句,lambda语句构建的其实是一个函数对象:
>>> g=lambda x,y : x*y
>>> g
<function <lambda> at 0x02B41EF0>
>>> g(2, 3)
6
例如:
>>> reduce(lambda x,y : x+y, range(1, 101))
5050

7,Switch语法结构

switch语句用于编写分支结构的程序,类似于if … elif … else语句,但switch语句比该语句调用速度快且结构清晰;
python实现分支结构的方法
首先,定义一个字典,其次,通过字典的get()获得相应的表达式,之后通过字典调用函数的表达式,代码形式如下:
{1: case1, 2:case2, ...}.get(x, lambda *arg, **key:)()
例如:计算数值的+,-,*,/
>>> x=1
>>> y=10
>>> result={'+':x+y, '-':x-y, '*':x*y, '/':x/y}
>>> o='+'
>>> print result.get(o)
11
实例:利用分支结构计算除数
#!/usr/bin/env python
#coding:utf8
number=int(raw_input(u'请输入一个正整数:'))
yeshu=srt(raw_input(u'请输入约数:'))
result={2: divmod(number, 2), 3: divmod(number, 3), 5: divmod(number, 5), 7: divmod(number, 7)}
print result.get(yeshu)
>>> number=6733
>>> print result.get(7)
(961, 6)

8,三个常用序列处理函数

filter()
表示当,前面的函数(function)对后面的序列(sequence)作用的时候,如果返回值为true,则会保留序列中的值。其函数作用相当于一个过滤器。
filter(funcation or None, sequence) -> list, tuple, or string
例子:
>>> filter(lambda x: x>10, range(20))
[11, 12, 13, 14, 15, 16, 17, 18, 19]
注意,这里的lambda x: x>10 (x>10 不用加if)

map()
可通过该函数对并行遍历之后的结果进行操作;map(function, sequence), 对序列sequence中每个元素都执行函数function操作,这里的function可以是系统内置函数,也可以是用户自定义函数。
例如:
>>> map(int, ['1', '2', '3', '4', '5'])
[1, 2, 3, 4, 5]
>>> map(lambda x: x.strip(), ['1\n', '2\n'])#[x.strip() for x in open('file')]
['1', '2']
>>> map(lambda x :int(x.strip()), ['1\n', '2\n'])
[1, 2]

reduce()
表示在序列中,取前两个元素用function函数作用后,结果再与第3个元素作用得出结果后再与第4个元素作用直到遍历序列中所有元素,得到最后一个结果(等差数列,等比数列)
reduce(function, sequence[, initial]) -> value
例如:
reduce(lambda x,y: x+y, [1, 2, 3, 4, 5])
等同于((((1+2)+3)+4)+5)
>>> reduce(lambda x,y: x+y, range(1, 101))
5050
>>> reduce(lambda x,y: x*y, range(1, 6))
120

main()函数的用法

main()函数是表示在脚本中,当所有运行内容即所有进程都写在def函数当中时,可通过main(),将要运行的主要函数的次序接到main()函数下面进行运行。例如:
def running(a, b):
····if a>b:
········return a,b
····if a<b:
········return#这里的return空,不影响后面的分析过程,表示跳过,如果用sys.exit()会影响其他分析流程的结果
def trim_all(r1fq, r2fq):
····pass
def get_args():#这个函数是在脚本运行时加入的输入参数,这里的返回值是,return的结果
····parser=argparse.ArgumentParser(description='')
····parser.add_argument("")
····return parser.parse_args()#返回输入的参数
def main():#这里定义的main函数,其内部各行均表示要运行的步骤
····myargs = get_args()
····trim_all(myargs.r1fq, myargs.r2fq)

if __name__ == '__main__':
····main()
当直接输入python XXXX.py时,则直接运行main()这个函数,而这个函数的第一步时运行myargs = get_args(),即运行def get_args():定义的函数,当输入参数都达到要求时,则运行trim_all(myargs.r1fq, myargs.r2fq)的内容。

9,实例判断文件是否是gzip格式

import gzip
def gzip_or_not(filename):
····try:
········gzip.open(filename,'rb').readline()
····except IOError:
········return open(filename,'rb')
····return gzip.open(filename,'rb')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值