【问题标题】:Does Python raise TypeErrors before short-circuiting a boolean?Python 在短路布尔值之前会引发 TypeErrors 吗?
【发布时间】:2012-06-25 18:18:45
【问题描述】:

我有一个函数可以在一个或多个指定日期(例如,第一天和第 15 天)执行每月任务。为了提高可用性,我想让用户只在他们只希望它发生时传入一个 int每月一天,或每月多个事件的整数列表。

monthly_event(days_of_month=1, event="paycheck") 
monthly_event(days_of_month=[1,15], event="bills", starting=date(2013,1,1))

在内部,该函数将遍历列表并执行与单个 int 相同的操作。

由于“int”不是可迭代的,当用户只传递一个 int 时,我需要做一些事情来避免 TypeError。我惊讶地发现使用“或”表达式并依靠短路不起作用 - TypeError 仍然发生。这是一个例子:

from datetime import date as date
dt = date.today()
days = 1
#days = [1,2]
if dt.day == days or dt.day in days:
    print "GOOD"
else:
    print "BAD"

我的第一个问题是:我是否误解了 Python,或者在布尔表达式短路之前,内部类型检查是否真的发生在整行代码上?这看起来很奇怪。

我的第二个问题是:Pythonic 的方法是什么?我想避免对“days”变量进行显式类型检查。使用 try/catch 只会使代码膨胀:

try:
    if dt.day == days:
        print "GOOD"
    else:
        print "BAD"
except TypeError:
    if dt.day in days:
        print "GOOD"
    else:
        print "BAD"

有什么明显的我忽略了吗?

【问题讨论】:

  • days = days if hasattr(days, "__iter__") else [days]
  • 或:import collections; days = days if isinstance(days, collections.Iterable) else [days]
  • 只要求days_of_month 始终是可迭代的(顾名思义!)。如果调用者只想要一天,他们可以传入一个单元组或一个列表或长度为 1 的集合。

标签: python short-circuiting typechecking


【解决方案1】:

我相信问题发生在dt.day != days(并且没有短路)时,Python会尝试dt.day in days表达式,并得到TypeError

【讨论】:

  • 呃 - 这有点尴尬。谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 2020-01-29
  • 2019-03-20
  • 2015-04-10
  • 2011-05-17
  • 2011-04-03
  • 2019-08-27
相关资源
最近更新 更多