函数是对程序逻辑进行结构化或过程化的一种编程方法。能将整块代码巧妙地隔离成易于管理的小块,把重复代码放在函数中而不是进行大量的拷贝。

一、函数创建 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测试开发圈”,了解更多测试教程!***

python 函数基础介绍的更多相关文章

  1. 《转》Python学习(17)-python函数基础部分

    http://www.cnblogs.com/BeginMan/p/3171977.html 一.什么是函数.方法.过程 推荐阅读:http://www.cnblogs.com/snandy/arch ...

  2. python 函数参数介绍

    python 函数参数介绍 python 使用过程总,总会遇到 *args,**kw形式的参数,总是一头雾水,而且网上介绍的或是叫法不一,为此专门深入实践进而了解了函数参数的使用 具体请看代码 #-* ...

  3. Python 函数基础、有序集合、文件操作(三)

    一.set 特点: set是一个无序且不重复的元素集合访问速度快:天生解决元素重复问题 方法: 初始化 >>> s1 = set()>>> print(type(s ...

  4. python函数基础学习

    函数的定义与调用: def 函数名(参数1,参数2): ‘’’函数注释’’’ print(‘函数体’) return 返回值 定  义:def关键字开关,空格之后接函数名和圆括号,最后冒号结尾 def ...

  5. 10分钟学会Python函数基础知识

    看完本文大概需要8分钟,看完后,仔细看下代码,认真回一下,函数基本知识就OK了.最好还是把代码敲一下. 一.函数基础 简单地说,一个函数就是一组Python语句的组合,它们可以在程序中运行一次或多次运 ...

  6. Python函数基础和函数参数

    函数的定义和函数的调用 return的作用 三种参数的定义 常用的内置函数 len() 函数基础 函数的定义 def 函数名(参数): pass return 表达式 pass在这里表示什么都没有,不 ...

  7. python 模块基础介绍

    从逻辑上组织代码,将一些有联系,完成特定功能相关的代码组织在一起,这些自我包含并且有组织的代码片段就是模块,将其他模块中属性附加到你的模块的操作叫做导入. 那些一个或多个.py文件组成的代码集合就称为 ...

  8. python函数基础

    一.基础 函数的定义 def 函数名(参数): ... 函数体 ... 返回值 #如果函数执行完毕也没有return语句时,自动return None. 空函数 如果想定义一个什么事也不做的空函数,可 ...

  9. python函数基础-参数-返回值-注释-01

    什么是函数 函数就是有特定功能的工具 # python中有内置函数(python解释器预先封装好的)与自定义函数(用户自定义封装的)之分 为什么要用函数 # 可以减少代码冗余,增加代码复用性 # 使代 ...

随机推荐

  1. Dubbo系列_概述

    一.本文目的         学习使用Dubbo也有一段时间了,准备写一个系列文章介绍Dubbo的相关知识和使用,供自己以后回顾和他人学习.有兴趣的同学可以加入群:74085440一起探讨 二.书写计 ...

  2. 【CodeVS 3123】高精度练习之超大整数乘法 &【BZOJ 2197】FFT快速傅立叶

    第一次写法法塔,,,感到威力无穷啊 看了一上午算导就当我看懂了?PS:要是机房里能有个清净的看书环境就好了 FFT主要是用了巧妙的复数单位根,复数单位根在复平面上的对称性使得快速傅立叶变换的时间复杂度 ...

  3. jquery-遍历each

    使用案例一 $.ajax({ url : webPath + "/clickCount", type : "POST", dataType : "js ...

  4. dede使用方法----如何自定义字段

    我们在用dede做东西的时候,有时候需要添加一些dede里面没有的字段,有dede后台里面可以添加相关的自段,下面我就以如何给产品添加一个价格的字段来讲述一下如何给dede添加字段,并且调用它. 1. ...

  5. Windows系统中path环境变量详解

    在学习JAVA的过程中,涉及到多个环境变量(environment variable)的概念,如PATH.正确地配置这些环境变量,是能够顺利学习.开发的前提.而经常出现的问题是:有的学习者能够按照提示 ...

  6. xml序列化方式

    public static class MySerializeXmlHelper { static MySerializeXmlHelper() { } private static object _ ...

  7. bzoj 1030 fail树dp

    dp[i][j][0]代表当前匹配到i号点走了j步且没到过单词节点,1代表到过,直接转移. #include<iostream> #include<cstdio> #inclu ...

  8. 【译】用boosting构建简单的目标分类器

    用boosting构建简单的目标分类器 原文 boosting提供了一个简单的框架,用来构建鲁棒性的目标检测算法.这里提供了必要的函数来实现它:100% MATLAB实现,作为教学工具希望让它简单易得 ...

  9. 【poj3141】 Distant Galaxy

    http://poj.org/problem?id=3141 (题目链接) 题意 给出平面上n个点,找出一个矩形,使边界上包含尽量多的点. solution 不难发现,除非所有输入点都在同一行或同一列 ...

  10. python *args **kwargs

    简单来说,当你传入的参数不能确定是几个的时候会用到 *args和**kwargs,这里星号后边只是个代号,你写成a也可以. 而这两者的区别是 如果是键值对就要用后者,反之前者就可以. 同时还可以用(a ...