【问题标题】:Function with different behavior depending on amount of input args根据输入参数的数量具有不同行为的函数
【发布时间】:2019-03-22 11:42:01
【问题描述】:

我想创建一个函数来检查是否是正确的时间进行操作,但我希望它灵活并检查作为函数输入的每对参数的条件。我写了一些代码,它在理论上应该是什么样子,现在我正试图弄清楚如何在代码中编写它。

def report_time(greater_than1=0, lower_than1=24, 
                greater_than2=0, lower_than2=24, 
                greater_than3=0, lower_than3=24, 
                ...
                greater_thanN=0, lower_thanN=24):    
    if greater_than1 < datetime.now().hour < lower_than1:
        logger.info('Hour is correct')
        return True

    if greater_than2 < datetime.now().hour < lower_than2:
        logger.info('Hour is correct')
        return True

    if greater_than3 < datetime.now().hour < lower_than3:
        logger.info('Hour is correct')
        return True

    ...

    if greater_thanN < datetime.now().hour < lower_thanN:
        logger.info('Hour is correct')
        return True

使用示例:

foo = report_time(16, 18)
foo = report_time(16, 18, 23, 24)
foo = report_time(16, 18, 23, 24, ..., 3, 5)

【问题讨论】:

  • 老实说,您的命名具有误导性,为什么greater_than1 在左边而lower_than1 在右边?
  • 因为大于等于低值,这真的重要吗?

标签: python function if-statement arguments


【解决方案1】:

更好的选择是让函数只接受一对参数,然后遍历函数外部的所有对,并检查在任何步骤中是否返回了True: p>

def report_time(greater_than=0, lower_than=24):
    return greater_than < datetime.now().hour < lower_than


start_times = [10, 12, 20]
end_times = [11, 15, 22]

for start, end in zip(start_times, end_times):
    if report_time(start, end):
        logger.info('Hour is correct')
        break

这可以使用mapany 缩短:

valid_times = map(report_time, start_times, end_times)
if any(valid_times):
    logger.info('Hour is correct')

另外,正如@AzatIbrakov 在his comment to another answer 中提到的那样,使用元组会更好。在这种情况下,您可以使用filter

def within_limits(limits=(0, 24)):
    return limits[0] < datetime.now().hour < limits[1]


time_limits = [(10, 11), (12, 15), (20, 22)]
if any(filter(within_limits, time_limits)):
    logger.info('Hour is correct')

【讨论】:

    【解决方案2】:

    你需要看*args:

    def multi_arg_pairs(*args):
        if len(args) % 2 == 1:
            raise ValueError("arguments must be an even number")
        for v1, v2 in zip(args[0::2], args[1::2]):
            print(v1, v2)
            # Do something with your value pairs
    
    multi_arg_pairs(1, 2, 3, 4)
    

    输出:

    1 2
    3 4
    

    【讨论】:

    • 我们可以告诉用户通过像multi_arg_pairs((1, 2), (3, 4))这样的间隔结束对而不是冗余检查,不需要检查长度和zipValueError将在解包过程中提出
    • 当然,请注意这与问题中所述的用法示例不一致。
    • 我们总是可以提供更好的方法,而不是推荐“刚刚工作”的解决方案,这样未来的谷歌人可能会选择更好的选择
    • 我同意,欢迎您编辑答案并添加更好的方法...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    相关资源
    最近更新 更多