3

click用来定义一个接受datetimes 和逗号分隔的参数列表的 CLI。

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

它有效,但围绕callbacks 的逻辑有点尴尬。拆分列表和转换为都datetime中断了简单的点击结构。有没有这样做的pythonic方式?

4

2 回答 2

4

您可以将丑陋的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)
于 2017-02-08T10:04:55.643 回答
0

我想要'05-Jul-2018'格式的日期字符串,以下对我有用

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

def getDate():
    return '09-Jul-2018' #you can have any code here

@click.command()
@click.option('--start_date', callback=check_date, default=lambda :getDate())
def f(symbols, start_date):
    print(symbols, start_date)

if __name__ == '__main__':
    f()

您可以在这里找到更多帮助

于 2018-07-28T08:00:26.323 回答