1. 程式人生 > >Python之函數三

Python之函數三

判斷 closure gpo 網頁爬蟲 pri .html 不能 color clock

函數名的本質

函數名本質上就是函數的內存地址。

1.可以賦值給其他變量,被引用

def func():
    print(in func)

f = func
print(f)

2.可以被當作容器類型的元素

def f1():
    print(f1)


def f2():
    print(f2)


def f3():
    print(f3)

l = [f1,f2,f3]
d = {f1:f1,f2:f2,f3:f3}
#調用
l[0]()
d[f2]()

3.可以當作函數的參數和返回值

def f1():
    print(f1
) def func1(argv): argv() return argv f = func1(f1) f()
第一類對象(first-class object)指
1.可在運行期創建
2.可用作函數參數或返回值
3.可存入變量的實體。

#可以當做普通變量用!

閉包

閉包函數:

內部函數包含對外部作用域而非全劇作用域變量的引用,該內部函數稱為閉包函數
#函數內部定義的函數稱為內部函數

def wrapper():
    name=laozhang
    def inner():
        print(name)
    inner()
    print
(inner.__closure__) #檢測是不是閉包 cell 就是b包 wrapper()

‘‘‘
輸出內容:

laozhang
(<cell at 0x0000000002167498: str object at 0x00000000026D6CB0>,)

‘‘‘

由於有了作用域的關系,我們就不能拿到函數內部的變量和函數了。如果我們就是想拿怎麽辦呢?返回呀!

我們都知道函數內的變量我們要想在函數外部用,可以直接返回這個變量,那麽如果我們想在函數外部調用函數內部的函數呢?

是不是直接就把這個函數的名字返回就好了?

這才是閉包函數最常用的用法

判斷閉包函數的方法__closure__

#輸出的__closure__有cell元素 :是閉包函數
def func(): name = eva def inner(): print(name) print(inner.__closure__) return inner f = func() f() #輸出的__closure__為None :不是閉包函數 name = egon def func2(): def inner(): print(name) print(inner.__closure__) return inner f2 = func2() f2()

閉包嵌套

def wrapper():
    money = 1000
    def func():
        name = eva
        def inner():
            print(name,money)
        return inner
    return func

f = wrapper()
i = f()
i()    

‘‘‘
eva 1000
‘‘‘

閉包的用處:

如果說內存函數是個閉包,python內部有一個機制,遇到閉包,會在內存中開啟一個內存空間(不會關閉),不會隨著函數的結束而關閉,能夠節省創建新內存的時間和使用頻率。

應用:網頁爬蟲

from urllib.request import urlopen

def index():
    url = "http://www.xiaohua100.cn/index.html"
    def get():
        return urlopen(url).read()
    return get

xiaohua = index()
content = xiaohua()
print(content)

裝飾器

在不改變原函數的基礎上,增加其他功能。(驗證登錄、測試時間、打印日誌)

1.簡單的裝飾器

import time
def func():
    print(更健康)
def timmer(f):
    def inner():
        start_time = time.clock()
        time.sleep(0.1)
        f()
        end_time = time.clock()
        print(執行時間為%s%(end_time - start_time))
    return inner
func = timmer(func)
func()

‘‘‘

更健康
執行時間為0.0998653700182556


‘‘‘
 

2.語法糖(簡單版本的裝飾器):

將@裝飾器的函數名,放在被裝飾的函數之前。

import time
def timmer(f):
    def inner():
        start_time = time.clock()
        time.sleep(0.1)
        f()
        end_time = time.clock()
        print(執行時間為%s%(end_time - start_time))
    return inner
@timmer  #相當於func = timmer(func)
def func():
    print(更健康)
func()  #inner()

‘‘‘

更健康
執行時間為0.1004682374539092


‘‘‘

3.帶參數的裝飾器

import time
def timmer(f):
    def inner(*args,**kwargs):
        start_time = time.clock()
        time.sleep(0.1)
        f(*args,**kwargs)
        end_time = time.clock()
        print(執行時間為%s%(end_time - start_time))
    return inner
@timmer  #相當於func = timmer(func)
def func(a):
    print(%s更健康%a)
@timmer   #相當於func1 = timmer(func1)
def func1(a,b):
    print(%s和%s更健康%(a,b))
func(‘老)  #
func1(‘老,殺毒軟件)

‘‘‘

老哥更健康
執行時間為0.10024377977801449
老哥和殺毒軟件更健康
執行時間為0.09983056346016456


‘‘‘

4.帶返回值的裝飾器

import time
def timmer(f):
    def inner(*args,**kwargs):
        start_time = time.clock()
        time.sleep(0.1)
        ret = f(*args,**kwargs)   #222
        end_time = time.clock()
        print(執行時間為%s%(end_time - start_time))
        return ret
    return inner
@timmer  #相當於func = timmer(func)
def func(a):   #a:老哥
    return 222
print(func(老哥))

‘‘‘

執行時間為0.0996239553012396
222


‘‘‘

5.通用裝飾器

def wrapper(func):
    def inner(*args,**kwargs):
        ‘‘‘執行函數前的操作‘‘‘
        ret = func(*args,**kwargs)
        ‘‘‘執行函數後的操作‘‘‘
        return ret
    return inner
@wrapper
def func():
    print(66)

Python之函數三