python 函数基础介绍
函数是对程序逻辑进行结构化或过程化的一种编程方法。能将整块代码巧妙地隔离成易于管理的小块,把重复代码放在函数中而不是进行大量的拷贝。
一、函数创建 def
函数创建格式如下:
def function_name(arguments): "function_documentation_string" function_body_suite
代码实例1-1:
def say_hello(): """say hello to somebody""" print "hello"
二、函数调用 ()
在python中,我们使用一对圆括号来调用函数。如上,运行代码实例1-1,是没有执行函数,没有任何输出的,编译器只是将say_hello变量加载到了内存。
此时可以运行say_hello(),将调用say_hello函数。正如你可能意识到的,任何输入的参数都必须放置在括号中。如下实例
代码实例2-1:
def say_hello(name): """say hello to somebody""" print "hello %s" % name say_hello("Milton")
代码实例2-1输出如:
hello Milton
三、函数参数(位置参数,默认参数,关键字参数,元组参数,字典参数)
代码实例3-1:
def say_hello(_from, _to, times=2): """somebody say hello to somebody repeats""" print "%s say hello to %s repeat %s times" % (_from, _to, times) say_hello("Milton", "Cherish") say_hello(_to="Cherish", _from="Milton", times=10)
代码实例3-1输出如下:
Milton say hello to Cherish repeat 2 times Milton say hello to Cherish repeat 10 times
正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需指定参数名即可,但记住一个要求就是,关键参数必须放在位置参数之后。
非固定参数
若你的函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数
代码实例3-2:
def say_hello(_from, _to, *args, **kwargs): """somebody say hello to somebody repeats""" print "%s say hello to %s " % (_from, _to) print "args:", args print "kwargs:", kwargs say_hello("Milton", "Cherish", "arg1", "arg2", name="guanfc", age=28) print "*" * 100 say_hello("Milton", "Cherish", ("arg1", "arg2"), name="guanfc", age=28) print "*" * 100 say_hello("Milton", "Cherish", "arg1", "arg2", {"name": "guanfc", "age": 28}) print "*" * 100 say_hello("Milton", "Cherish", "arg1", "arg2", **{"name": "guanfc", "age": 28})
实例3-2输出如下:
Milton say hello to Cherish args: ('arg1', 'arg2') kwargs: {'age': 28, 'name': 'guanfc'} **************************************************************************************************** Milton say hello to Cherish args: (('arg1', 'arg2'),) kwargs: {'age': 28, 'name': 'guanfc'} **************************************************************************************************** Milton say hello to Cherish args: ('arg1', 'arg2', {'age': 28, 'name': 'guanfc'}) kwargs: {} **************************************************************************************************** Milton say hello to Cherish args: ('arg1', 'arg2') kwargs: {'age': 28, 'name': 'guanfc'}
def say_hello(_from, _to, *args, **kwargs) 函数定义中,*args代表元组,**kwargs代表键值对。
当调用如: say_hello("Milton", "Cherish", "arg1", "arg2", name="guanfc", age=28) 时,
“Milton”对应形参“_from”,
“Cherish”对应形参“_to”,
"arg1"和"arg2"对应形参*args,
name="guanfc",age=28 对应形参**kwargs
故输出如:
Milton say hello to Cherish args: ('arg1', 'arg2') kwargs: {'age': 28, 'name': 'guanfc'}
当调用如:say_hello("Milton", "Cherish", "arg1", "arg2", {"name": "guanfc", "age": 28}) 时,
“Milton”对应形参“_from”,
“Cherish”对应形参“_to”,
"arg1","arg2",{"name":"guanfc","age":28} 对应形参*args,
没有实参对应形参**kwargs
故输出如:
Milton say hello to Cherish args: ('arg1', 'arg2', {'age': 28, 'name': 'guanfc'}) kwargs: {}
如果想直接将字典作为实参传入 {"name": "guanfc", "age": 28} 赋值给形参**kwargs,则需要在传入时,在前面添加**,
如say_hello("Milton", "Cherish", "arg1", "arg2", **{"name": "guanfc", "age": 28})
故输出如:
Milton say hello to Cherish args: ('arg1', 'arg2') kwargs: {'age': 28, 'name': 'guanfc'}
如果同时具有元组参数*args和字典参数**kwargs,字典参数**kwargs要放在最后
四、传递函数
所有的对象都是通过引用来传递的,函数也不例外。当对一个变量赋值时,实际是将相同对象的引用赋值给这个变量。如果对象是函数的话,这个对象所有的别名都是可调用的。如:
>>> def say_hello(): ... print "say hello~" ... >>> bar=say_hello >>> bar() say hello~ >>>
当我们把say_hello赋值给bar时,bar和say_hello引用了同一个函数对象,所以bar能以和say_hello相同的方式来调用函数,bar()
我们甚至可以把函数作为参数传入到其他函数来进行调用,如:
>>> def say_hello(): ... print "say hello~" ... >>> >>> def bar(argfunc): ... argfunc() ... >>> >>> bar(say_hello) say hello~ >>>
五、匿名函数 lambda
lambda [arg1[,arg2,... argN]] : expression
核心笔记:lambda 表达式返回可调用的函数对象
def add(x,y):return x+y <==> lambda x,y:x+y
>>> a=lambda x,y=2:x+y >>> a(0) 2 >>> a(1) 3 >>> a(4,5) 9 >>>
六、内建函数
filter():给定一个对象的序列和一个“过滤”函数,每个序列元素都通过这个过滤器进行筛选,保留函数返回为真的对象。
代码实例6-1:
def select_server(server): if server > 5: return True server_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print filter(select_server, server_list) print filter(lambda server: server > 5, server_list)
代码实例6-1输出如:
[6, 7, 8, 9] [6, 7, 8, 9]
map():给定一个对象的序列和一个“功能”函数,将函数作用在序列的每个元素上,然后创建由每次函数应用组成的返回值列表。
代码实例6-2:
def map_server(server): server = int(server) + 10 return server server_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print map(map_server, server_list) print map(lambda server: server + 10, server_list)
代码实例6-2输出如:
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
七、变量作用域(局部变量,全局变量)
代码实例7-1:
#!/usr/bin/env python # -*- coding: utf-8 -*- # 全局变量 server = 0 role = "Milton" def map_server(): global server # 声明全局变量 server = 100 role = "Cherish" # 局部变量 map_server() print server # 输出全局变量,在map_server函数中已被修改-->server==100 print role # 输出全局变量--> role == "Milton"
代码实例7-1输出如:
100 Milton
八、闭包
>>> def counter(start_at=0): ... count=[start_at] ... def incr(): ... count[0]+=1 ... return count[0] ... return incr ... >>> >>> count=counter(5) >>> count() 6 >>> count() 7 >>> count2=counter(100) >>> count2() 101 >>> count2() 102 >>> count() 8 >>>
九、装饰器(无参,有参,函数)
装饰器,主要为了实现程序设计的开放封闭原则,在原实现函数不修改的基础上,对原函数功能进行扩展。最终提供的调用方式保持一致。
封闭:已实现的功能代码块
开放:对扩展开放
无参装饰器
代码实例9-1:
#!/usr/bin/env python # -*- coding: utf-8 -*- def wrapper(main_func): def inner(): print "I am before login" main_func() print "I am after login" return inner @wrapper def login(): print "do login" # 调用方 login()
代码实例9-1输出如:
I am before login do login I am after login
关键代码分析:
@wrapper
def login():
print "do login"
等同于 当执行login()时
1.login=wrapper(login)
2.login()
代码实例9-1运行过程等同如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- def wrapper(main_func): def inner(): print "I am before login" main_func() print "I am after login" return inner def login(): print "do login" # 调用方 login = wrapper(login) login()
带参装饰器(被修饰的函数带参,装饰器本身带参)
代码实例9-2:
#!/usr/bin/env python # -*- coding: utf-8 -*- def wrapper(main_func): def inner(*args, **kwargs): print "I am before login" main_func(*args, **kwargs) print "I am after login" return inner @wrapper def login(name, passwd): print "do login,name=%s,passwd=%s" % (name, passwd) # 调用方 login("Milton", 123456)
代码实例9-3:
#!/usr/bin/env python # -*- coding: utf-8 -*- def wrapper(action): def outer(main_func): def inner(*args, **kwargs): print "action == %s" % action main_func(*args, **kwargs) print "I am after login" return inner return outer @wrapper("before login") def login(name, passwd): print "do login,name=%s,passwd=%s" % (name, passwd) # 调用方 login("Milton", 123456)
代码实例9-3输出如:
action == before login do login,name=Milton,passwd=123456 I am after login
关键代码分析:
python解释器从上往下扫描到
@wrapper("before login") 时,执行了
login=wrapper("before login")(login)
#!/usr/bin/env python # -*- coding: utf-8 -*- def wrapper(action): def outer(main_func): def inner(*args, **kwargs): print "action == %s" % action main_func(*args, **kwargs) print "I am after login" return inner return outer # @wrapper("before login") def login(name, passwd): print "do login,name=%s,passwd=%s" % (name, passwd) # 调用方 login=wrapper("before login")(login) login("Milton", 123456)
十、生成器
什么是Python式的生成器?从语法上讲,生成器是一个带yield语句的函数。一个函数或者子程序只返回一次,但一个生成器能暂停执行并返回一个中间的结果--那就是yield语句的功能,返回一个值给调用者并且暂停执行。当生成器的next()方法被调用时,它会准确地从离开地方继续执行。当生成器的send()方法被调用时,yield会接收send方法传入的实参,并且从yield暂停的地方开始继续执行。
yield输出,代码实例10-1:
#!/usr/bin/env python # -*- coding: utf-8 -*- def simple_gen(): yield 1 yield '2 -->punch!' # 调用next()方法 gen = simple_gen() print gen.next() print "离开去干点别的事" print gen.next() print "*" * 20 # 使用for循环 for item in simple_gen(): print item
代码实例10-1输出如:
1 离开去干点别的事 2 -->punch! ******************** 1 2 -->punch!
yield接收输入,代码实例10-2:
#!/usr/bin/env python # -*- coding: utf-8 -*- def simple_gen(): print "waiting for name." while True: name = yield print name gen = simple_gen() # 创建生成器对象 gen.next() # 执行next()方法时,程序运行到name=yield就退出,等待send传入参数。 gen.send("Milton") # 一旦调用send()方法,回到yield退出位置,yield接收send实参,并且继续往下运行 gen.send("Cherish")
实例10-2输出如:
waiting for name. Milton Cherish
在交互端如:
>>> def simple_gen(): ... print "waiting for name." ... while True: ... name=yield ... print name ... >>> >>> gen=simple_gen() >>> gen.next() waiting for name. >>> gen.send("Milton") Milton >>> gen.send("Cherish") Cherish >>> gen.send("guanfc") guanfc >>>
通过yield实现在单线程的情况下实现并发运算的效果
代码实例10-3:
#!/usr/bin/env python # -*- coding: utf-8 -*- import time def consumer(name): print("%s 准备抢红包啦!" % name) while True: money = yield print("红包[%s]来了,被[%s]抢了!" % (money, name)) def producer(): c1 = consumer('A') c2 = consumer('B') c1.next() c2.next() print("群主准备发红包啦!") for i in range(3): time.sleep(1) print("群主发了两个红包!") c1.send(bytes(i) + "-part1") c2.send(bytes(i) + "-part2") producer()
代码实例10-3输出如下:
A 准备抢红包啦! B 准备抢红包啦! 群主准备发红包啦! 群主发了两个红包! 红包[0-part1]来了,被[A]抢了! 红包[0-part2]来了,被[B]抢了! 群主发了两个红包! 红包[1-part1]来了,被[A]抢了! 红包[1-part2]来了,被[B]抢了! 群主发了两个红包! 红包[2-part1]来了,被[A]抢了! 红包[2-part2]来了,被[B]抢了!
***微信扫一扫,关注“python测试开发圈”,了解更多测试教程!***