python閉包與裝飾器
閉包
函數(shù)和對其周圍狀態(tài)(lexical environment崔泵,詞法環(huán)境)的引用捆綁在一起構(gòu)成閉包(closure)博助。也就是說险污,閉包可以讓你從內(nèi)部函數(shù)訪問外部函數(shù)作用域。
常用語言基本都實現(xiàn)了閉包富岳。
閉包中最重要的是蛔糯,我們返回了一個內(nèi)部函數(shù)。
def power(n):
def func(m):
return m**n
return func
在power
函數(shù)中窖式,我們定義了一個func
函數(shù)蚁飒,func
函數(shù)接收底數(shù)m
,從外部power
函數(shù)中拿到指數(shù)n
萝喘,返回冪m**n
淮逻。
這個簡單的定義可以使我們獲得能夠進行任何指數(shù)操作的函數(shù)。
power2 = power(2)
power5 = power(5)
power10 = power(10)
print(power2(4))
print(power5(4))
print(power5(10))
out:
16
1024
100000
閉包使我們能夠通過函數(shù)創(chuàng)造各種各樣的類似函數(shù)蜒灰,是不是很神奇?
今天我也寫了一個閉包弦蹂。它能夠接收gtf文件返回某個染色體位置的基因。
def get_gene(file="Homo_sapiens_GRCh37_87_geneonly.gtf"):
gtf = pd.read_csv(file, header=None, sep='\t')
gtf['gene_name'] = gtf[8].apply(lambda x: re.search(r'gene_name \"(.*?)\"', x).group(1))
def fetch(chrom, start):
start = int(start)
value = gtf[(gtf[0] == chrom) & (gtf[3] <= start) & (gtf[4] >= start)]['gene_name'].tolist()
if value:
return value[0]
else:
return None
return fetch
創(chuàng)建具體的fetch
强窖。
fetch = get_gene()
fetch(10,103454465)
out:
'FBXW4'
這樣就可以避免重復操作文件凸椿,變量值也不會暴露在環(huán)境中。
裝飾器
裝飾器的作用就是為已經(jīng)存在的對象添加額外的功能翅溺。
其實裝飾器也是一個閉包脑漫,但是我們一般不用裝飾器修改函數(shù)功能。
def square(n):
print(f'square {n}')
return n**2
square(2)
out:
square 2
4
寫一個裝飾器咙崎,能夠在函數(shù)執(zhí)行前打印執(zhí)行時間优幸。
import time
def decorator(func):
def wrapper(*args,**kwargs):
print(time.time())
return func(*args,**kwargs)
return wrapper
@decorator
def square(n):
print(f'square {n}')
return n**2
out:
1597498618.3460186
square 2
4
其實@decorator
實現(xiàn)的就是square = decorator(square)
,這樣就用返回的函數(shù)替換了原來的square
褪猛,但是decorator
會在打印時間后繼續(xù)執(zhí)行原函數(shù)网杆,原函數(shù)在裝飾器內(nèi)部以外部函數(shù)變量存在(閉包,不是嗎),這樣就為函數(shù)添加了額外的功能碳却。
學會队秩,點贊!