1. 程式人生 > >流程python學習筆記:第五章(1)

流程python學習筆記:第五章(1)

第五章:一等函式
在python中一切都可以視作為物件,包括函式。我們來看個例子:
def function_try():
    '''it is funciton try doc'''
    print 'function_try'


if __name__=="__main__":
    print function_try.__doc__
    print function_try.__name__
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
it is funciton try doc
function_try
在這裡__doc__輸出了函式function_try在開頭的幫助。__name__則是輸出了具體的函式名
我們還可以將函式名賦值給變數。通過變數的形式來訪問
def function_try():
    '''it is funciton try doc'''
    print 'function_try_print'


if __name__=="__main__":
    fun=function_try
    print fun.__doc__
    print fun.__name__
    fun()
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
it is funciton try doc
function_try
function_try_print
函式也可以通過引數被傳遞給另外一個函式。
def function_try():
    '''it is funciton try doc'''
    print 'function_try_print'

def function_try1(fun):
    print fun.__doc__
    print fun.__name__
    fun()

if __name__=="__main__":
    f=function_try
    function_try1(f)
下面來介紹下函式的高階用法。
假設有一字元列表,想通過各個字元的長度來進行排序。我們首先想到的是下面的方法。用sort的方法,並在key中指明排序的依據。在這裡用到了lambda來得到每個元素的長度。
fruits=['strawberry','fig','apple','cherry','rasberry','banana']
fruits.sort(key=lambda x:len(x))
print fruits
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
['fig', 'apple', 'cherry', 'banana', 'rasberry', 'strawberry']
還可以直接用sorted的方法。不同的是sorted是另外返回一個排序後的列表,原列表fruits並沒有發生改變
fruits=['strawberry','fig','apple','cherry','rasberry','banana']
ret=sorted(fruits,key=len)
print 'after sorted %s' % ret
print 'before sorted %s' % fruits
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
after sorted ['fig', 'apple', 'cherry', 'banana', 'rasberry', 'strawberry']
before sorted ['strawberry', 'fig', 'apple', 'cherry', 'rasberry', 'banana']
下面來介紹幾個高階函式:map,filter,reduce
首先來看下map的定義:

map(functioniterable...)

Apply function to every item of iterable and return a list of the results. Ifadditional iterable arguments are passed,function must take that many arguments and isapplied to the items from all iterables in parallel. If one iterable is shorterthan another it is assumed to be extended withNoneitems. If function isNone, the identity function isassumed; if there are multiple arguments, map() returns a list consisting of tuplescontaining the corresponding items from all iterables (a kind of transposeoperation). The iterable arguments may be a sequence or anyiterable object; the result is always a list.

簡單歸納就是對於可迭代物件iterable中的每一個元素應用function方法。並將結果做為list返回
來看下例子:
def add_num(n):
    return n+1

if __name__=="__main__":
    print map(add_num,range(1,6))
range(1,6)中的各個元素都被add_num呼叫然後生成一個列表。其實效果相當於[add_num(n) for n in range(1,6)].因此map可以看做是一個列表推導式
我們再來另外一個應用
def add_num(a,b,c):
    return a+b+c

if __name__=="__main__":
    print map(add_num,range(1,6),range(7,12),range(11,16))
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
[19, 22, 25, 28, 31]
這個寫法的作用是將3個range中的元素按照順序依次想加。這樣寫是不是比逐個遍歷要方便很多。
再來看下filter。
s=[1,2,3,4,5]
print filter(lambda x:x>3,s)
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
[4, 5]
Filter的作用在於根據第一個引數為true還是false來進行過濾。上面例子中將大於3的數值過濾出來。
下面介紹下reduce的作用。我們先來看下說明:
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
上面的說明很形象了,就是將引數累加的應用於函式中。就好比我們要對1到100進行求值。程式碼如下。效果等同於sum(range(100))
from operator import add
print reduce(add,range(100))
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
4950
對於reduce請注意這句話:Apply a function of two arguments cumulatively to the items of a sequence,意思是傳入的函式必須接受2個引數。意味著傳輸的計算源必須至少是有2個。
前面介紹到可以把函式當做物件。那麼我們可以像呼叫函式那樣呼叫類麼。答案是肯定的。只需要我們重寫類中的__call__就可以了
class function_try:
    def __init__(self,value):
        self.data=value
    def __call__(self, *args, **kwargs):
        print 'function try was called'
        for a in args:
            print a

if __name__=="__main__":
    f=function_try(3)
    print f(3,2)
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
function try was called
3
2
當我們用print f(3,2).起作用的其實是__call__方法。
除了__doc__, __name__這些函式還有很多屬性。可以用dir的方法進行檢視
def add_num(a,b,c):
    return a+b+c
print dir(add_num)
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
可以看到上面這麼多的方法。類中也有很多的屬性,哪些是函式特有的呢。可以寫一個空類和空的函式來進行對比
class c:
    pass

def func():
    pass


if __name__=="__main__":
    print sorted(set(dir(func))-set(dir(c)))