2015-11-04 22 views
2

我有一些python腳本的行爲取決於運行腳本時用戶傳遞的條件。Python中的條件全局Lambdas

假設我有兩個lambda表達式; verbose_printmath_foo,我想用它來根據我的-m還是-v標誌被設置來有條件地在python腳本中做某些事情。

from __future__ import print_function # Future-proofing 
import argparse #args 

verbose_print = lambda x: 0 
math_foo = lambda x, y: 0 

def main_func(args): 
    verbose_print("WILL ONLY PRINT WHEN VERBOSE") 
    #other main function stuff 
    conditional_result = math_foo(12,45) 

if __name__ == "__main__": 
    started_at = time.time() 
    #declare argparse logic separately from main functionality 
    parser = argparse.ArgumentParser() 
    parser.add_argument('-v', '--verbose', action='store_true') 
    parser.add_argument('-m', '--use_math', action='store_true') 
    args = parser.parse_args() 
    verbose_print("Began...") # won't print since this will always be lambda x:0 
    global verbose_print 
    verbose_print = lambda x: print(x) if args.verbose and not args.quiet else 0 
    global math_foo 
    math_foo = lambda x, y: x^(x+y) if args.use_math else y 
    main_func(args) #run main function  
    finished_at = time.time()   
    verbose_print("Finished (Took {} seconds)".format((finished_at-started_at))) 

這種方法證明是可行的,但我很好奇這種事情是否有更多pythonic解決方案。例如,如果我曾經想用這個文件作爲import,但仍然需要日誌詳細事件,那麼我需要在該新文件中重新定義我的lambda。而不是兩個lambda,如果有十一個呢?每次進口時我都不想手動設置11個lambda表達式!

有沒有更好的方式處理這種有條件的行爲?我正在計劃使用python來創建更多的個人腳本,並且我想知道我是否正在走正確的道路。

+5

聽起來像'logging'模塊的工作。您可以簡單地設置記錄器的日誌級別,甚至可以維護兩個不同的記錄器,每個記錄器都有自己的級別。 – shx2

+0

對我的例子來說是一個很好的解決方案,但是如果lambda是更少的print-y,比如'math_foo = lambda x,y:x ^(x + y)如果args.use_math else y'? – Andrew

+0

稍微高效一點,因爲你不打包'print':'verbose_print = print如果args.verbose而不是args.quiet else lambda x:0'。 (假設你在運行過程中沒有更新'args' ...) – chepner

回答

2

當我看到像verbose_print = lambda x: 0我詛咒的可怕的教程,試圖解釋lambda以這種奇怪的方式。 lambdas是匿名函數,當你不想定義一個命名函數的時候就會使用它......但這正是分配所做的。只需定義打印功能,並在處理參數時在主設置中設置verbose

verbose = False 

def verbose_print(msg): 
    global verbose 
    if verbose: 
     print(msg) 

if __name__ == "__main__": 
    started_at = time.time() 
    #declare argparse logic separately from main functionality 
    parser = argparse.ArgumentParser() 
    parser.add_argument('-v', '--verbose', action='store_true') 
    parser.add_argument('-m', '--use_math', action='store_true') 
    args = parser.parse_args() 
    verbose_print("Began...") # won't print since this will always be lambda x:0 
    global verbose 
    verbose = args.verbose and not args.quiet 
    global math_foo 
    math_foo = lambda x, y: x^(x+y) if args.use_math else y 
    main_func(args) #run main function  
    finished_at = time.time()   
    verbose_print("Finished (Took {} seconds)".format((finished_at-started_at))) 
+0

這是真實的故事:) +1 –

+0

這是我一起去的解決方案,我做的唯一變化就是在我的'if __name__ =='__main __「:'語句中擺脫'global verbose'和'global math_foo'因爲他們拋出語法錯誤。謝謝! – Andrew

1

如在評論中提到的,你應該使用日誌模塊

parser.add_argument('-v', '--verbose', action="count", help="verbose level... repeat up to -vvvv.") 

... 
args.verbose = min(args.verbose,4) 
my_logging_logger.setLevel("CRITICAL ERROR WARN INFO DEBUG".split()[args.verbose]) 

同樣,如果它是別的東西

some_fn = lambda x:0 
data = {"verbose":lambda x:x**2+sqrt(x),"quiet":lambda x:-1} 
for k in dir(args): #I think you can do this ... I dont use argparse enough 
    if k in data: 
     some_fn = getattr(args,k) 
     break; 
+0

有趣的解決方案!我認爲它可能是'vars(args)'而不是'dir(args)',但我會給這個鏡頭。 – Andrew