2017-02-08 3 views
1

Я использую click для определения CLI, который принимает datetime s и разделенный запятыми список параметров.Преобразование типа клика

import click 

def valid_date(s): 
    try: 
     return dt.strptime(s, "%Y-%m-%d") 
    except ValueError: 
     msg = "Not a valid date: '{0}'.".format(s) 
     raise Exception(msg) 
    except TypeError: 
     return None 

split_parameter = lambda _, __, s: s.split(",") 
check_date = lambda _, __, s: valid_date(s) 


@click.command() 
@click.argument('symbols', callback=split_parameter) 
@click.option('--start_date', callback=check_date) 
@click.option('--end_date', callback=check_date) 
@click.option('--file_name') 
def f(symbols, start_date, end_date, file_name): 
    return None 

Это работает, но логика вокруг callback s немного неловко. Как разделение списка, так и преобразование в datetime прерывает приятную простую структуру щелчка. Есть ли питонический способ сделать это?

ответ

2

Вы можете инкапсулировать уродливое lambda _, __, x участие в декоратора:

import click 
from datetime import datetime as dt 

def click_callback(f): 
    return lambda _, __, x: f(x) 

def check_date(s): 
    try: 
     return dt.strptime(s, "%Y-%m-%d") 
    except ValueError: 
     msg = "Not a valid date: '{0}'.".format(s) 
     raise Exception(msg) 
    except TypeError: 
     return None 

@click.command() 
@click.argument('symbols', callback=click_callback(lambda s: s.split(','))) 
@click.option('--start_date', callback=click_callback(check_date)) 
@click.option('--end_date', callback=click_callback(check_date)) 
@click.option('--file_name') 
def f(symbols, start_date, end_date, file_name): 
    print(symbols, start_date, end_date, file_name) 

if __name__ == '__main__': 
    f() 

Или как это (только соответствующая часть показана):

def click_callback(f): 
    return {'callback': lambda _, __, x: f(x)} 

@click.command()   # vvvvvvvvvvvvvvvv 
@click.argument('symbols', **click_callback(lambda s: s.split(','))) 
@click.option('--start_date', **click_callback(check_date)) 
@click.option('--end_date', **click_callback(check_date)) 
@click.option('--file_name') 
def f(symbols, start_date, end_date, file_name): 
    print(symbols, start_date, end_date, file_name) 
Смежные вопросы