什么是函数
函数式对程序逻辑进行结构化或者过程化的一种编程方法。能将整块代码巧妙地隔离成易于管理的小块,把重复代码放到函数中而不是进行大量的拷贝——这样既节省空间,也有助于保持一致性,因为你只需改变单个的拷贝而无须去寻找再修改大量的复制代码的拷贝。
函数可以有不同的形式出现。下面简单展示了一些创建、使用、或者引用函数的方法。
declaration/definition def foo(): print 'bar'
function object/reference foo
function call/invocation foo()
函数vs过程
我们经常拿函数和过程比较。两者都是可以被调用的实体,但是传统意义上的函数或者“黑盒”,可以不带任何输入参数,经过一定的处理,最后向调用者传回返回值。其中一些函数则是布尔类型的,返回一个“是”或者“否”的回答,更确切的说,一个非零和零值。而过程是简单、特殊、没有返回值的函数。**python的过程就是函数,因为解释器会隐式地返回默认值None。
算术游戏(easyMath.py)
#!/usr/bin/env python
#
from operator import add, sub
from random import randint, choice
ops = {'+': add, '-': sub}
MAXTRIES = 2
def doprob():
op = choice('+-')
nums = [randint(1,10) for i in range(2)]
nums.sort(reverse=True)
ans = ops[op](*nums)
prd = '%d %s %d=' %(nums[0],op,num[1])
oops = 0
while True:
try:
if int(raw_input(pr)) == ans:
print 'correct'
break
if oops == MAXTRIES:
print 'answer \n%s%d'%(pr, ans)
else:
print 'incorrect ... Try again'
oops += 1
except (KeyboardInterrupt, EOFError, ValueError):
print 'invalid input ... try again'
def main():
while True:
try:
opt = raw_input('Again? [y]).lower()
if opt and opt[0] == 'n':
break
except (KeyboardInterrupt, EOFError):
break
if __name__ == '__main__':
main()
函数(与方法)装饰器
装饰器背后的主要动机源自Python面向对象编程。装饰器是在函数调用之上的修饰。这些修饰仅在当声明一个函数或者方法的时候,才会应用的额外调用。
装饰器的语法以@开头,接着是装饰器函数的名称和可选参数。紧跟着装饰器声明的是被修饰的函数和装饰器函数的可选参数
@decorator(dec_opt_args)
def func2Bdecorated(func_opt_args):
:
- 有参数和无参数的装饰器
@deco
def foo(): pass
#等价于
foo = deco(foo)
@decomaker(deco_args)
def foo(): pass
#等价于
foo = decomaker(deco_args)(foo)
@deco1(deco1_args)
@deco2
def foo(): pass
#等价于
foo = deco1(deco1_args)(deco2(foo))
什么是装饰器
现在我们知道装饰器实际就是函数。我们也知道他们接受函数对象。但它们是怎么样处理那些函数的呢? 一般来说,当你包装一个函数的时候,你最终会调用它。最棒的是我们能在包装的环境下在合适的时机调用它。
可以用装饰器用来:
- 引入日志
- **增加计时逻辑来检测性能
-
给函数加入事物的能力
对于用python来创建企业级的应用,支持装饰器的特性是非常有必要的。
使用函数装饰器的例子(deco.py)
#!/usr/bin/env python
from time import ctime, sleep
def tsfunc(func):
def wrappedFunc():
print '[%s] %s() called' %(ctime(), func.__name__)
return func()
return wrappedFunc
@tsfunc
def foo():
pass
foo()
sleep(4)
for i in rang(2):
sleep(1)
foo()
传递函数
函数式可以被引用的(访问或者以其他变量作为别名),也作为参数传入函数。,以及作为列表和字典等容器对象的元素函数有一个独一无二的 特征使它同其他对象区分开来,那就是函数是可以被调用的。
因为所有的对象是都是通过引用来传递的,函数也不例外。当对一个变量赋值时,实际是将相同对象的引用赋值给变量。如果对象是函数的话,这个对象的所有别名都是可以被调用的。
>>> def foo():
... print 'in foo()'
...
>>> bar = foo
>>> bar()
in foo()
#当我们把foo赋值给bar时,bar和foo引用了同一个函数对象,所以能以和调用foo()相同的方法来调用bar()。确定你明白"foo"是函数的引用,而"foo()" 是函数的调用。
传递和调用(内建)函数(numConv.py)
#!/usr/bin/env python
def convert(func,seq):
'conv. sequence of numbers to same type'
return [func(eachoNum) for eachNum in seq]
myseq = (123, 45.67, -6.2e8, 99999L)
print convert (int,myseq)
print convert (long, myseq)
print convert (float, myseq)