函数是对程序逻辑进行结构化或过程化的一种编程方法。能将整块代码巧妙地隔离成易于管理的小块,把重复代码放到函数中而不是进行大量的拷贝--这样既能节省空间,也有助于保持一致性。
python可以创建四种函数:
全局函数:定义在模块中
局部函数:嵌套在其他函数中
lambda函数:表达式
方法:与特定数据类型关联的函数,并且只能与数据类型关联一起使用(定义在类中的函数)
def
def是一个可执行语句
def创建了一个对象并赋值给一个变量名(即函数名)
return
函数是通过return语句将计算得到的值传递给调用者的,返回值成为函数调用的结果。
如果函数执行了return语句,那么函数的生命就结束了,return 语句后面的代码都不会执行。函数里只能执行一次return语句,但可以写多条return语句。
函数返回结果
没有return语句,没有返回值,返回对象类型是none;(如果在构造函数中,没有返回值,记得在最后加上 return none)
返回一个值的时候,类型为object;
返回多个值的时候,python会把返回值聚集起来,以元组的形式返回;
def test():
print 'haha'
res = test()
>>>haha
print res
>>>None
type(res)
>>>NoneType
调用函数
使用()对函数进行调用;
def t1():
print 'hello'
return None
t1
>>> <function __main__.t1>
print t1
>>> <function t1 at 0x00000000038B8DD8>
t1()
>>> hello
函数作用域
- python创建、改变、查找变量名都是在名称空间中进行
- 在代码中变量名被赋值的位置决定了其能被访问到的范围
- 函数定义了本地作用域,而模块定义了全局作用域
- 每个模块都是一个全局作用域,因此,全部作用域的范围就限于单个程序文件
- 每次对函数的调用夺回创建一个新的本地作用域,赋值的变量除非为全局变量,否则均为本地变量
- 所有的变量名都可以归纳为本地、全局或内置(由__builtin__模块提供)
变量名解析:LEGB原则
tml.png变量名引用分三个作用域进行:首先是本地、之后是外层函数内、接着是全局(模块),最后是内置;
参数匹配模型
默认情况下,参数通过其位置进行传递,从左到右,个数相同;
但也可以通过关键字参数、默认参数或参数容器等改变这种机制:
-
定义默认参数时,默认参数放在最后
-
可变参数:定义函数时使用*开头的参数,可用于收集任意多给予位置或关键字的参数;可变参数放在最后。
可变参数,输出为元组
m = 3; n = 4; l = [1,2]
def f10(*arg):
print arg
f10(l)([1, 2],)
f10(l, m)
([1, 2], 3)
f10(l, m, n)
([1, 2], 3, 4)def f11(x, *y):
print x, y
f11(m,n,l)3 (4, [1, 2])
#可变参数解包
l3 = ['a', 'b', 'c']
def f17(x, y, z):
print x, y ,z
f17(*l3) #个数需匹配,如果l3是四个,就会报错
>>> a b c
f17(m, *l3)
>>> 3 a b
lambda
lambda是表达式,不是语句,不是代码块
参数是可选的,lambda表达式返回的是一个可调用函数对象
f18 = lambda x, y: x + y
f18
>>> <function __main__.<lambda>>
f18(1, 2)
>>> 3
# 收集可变参数的lambda
m = 3; n = 4; l = [1,2]
f19 = lambda *z: z
f19(m, n)
>>> (3, 4)
f19(m, n, l)
>>> (3, 4, [1, 2])
函数的设计规范
- 降低耦合性:
- 通过函数接受输入,以及通过return产生输出以保证函数的独立性(少使用print);
- 尽量少使用全局变量进行函数间通信;
- 不要在函数中修改可变类型的参数;
- 避免直接改变定义在另外一个模块中的变量;
- 聚合性:
- 每个函数保持单一性功能;
- 函数功能应保持简单,避免过于复杂;
网友评论