这是python中用于验证日期条目的算法。我想知道这究竟是什么意思“if day”(语义)。我只知道“if”对布尔表达式的影响,而不是整数或数组等变量(我见过一些)。有人有解释吗?
def valid_day(day):
if day and day.isdigit():#if day
day = int(day)
if day > 0 and day <= 31:
return day
在python中,写作
if var:
与写作具有相同的效果
if bool(var):
(其中bool
是内置的bool
类型,它也可以作为bool对象的构造函数)。
如果该值已经是bool(值为True或False),则含义很明确 - bool(var)返回相同的值。对于其他类型,几乎总是转换为bool avaliable,这取决于类型。对于整数(如在C中),它与var!= 0相同;对于列表或字符串或字符串,它与len(var)!= 0相同,依此类推。你可以在python文档中找到它。
当您定义自己的类时,您可以通过def __nonzero__(self):
定义一个方法,该方法将在此上下文中调用(当您的对象明确地传递给bool
时,或者隐含地传递给if
- 或while
)。
一个值得注意的例外:numpy数组对象不会转换为bool(它们引发异常)。它们需要使用(arr!=0).any()
或(arr>0).all()
等构造进行显式转换
在类似的方面:不要养成写任何一个的习惯
if x == True: # This only works as expected when x is a bool
if x is True: # Can be useful but you need to understand what it really means.
if x == None: # Often works as expected, except when it doesn't
应该始终与无比较
if x is None:
(或)if x is not None:
只有一个None
对象,x is None
会告诉你x是否指向那个对象,并且总是给你一个bool(如果是,则为True,对于任何其他对象为False)。比较x==None
(我在开始使用Python时经常犯的错误)通常会起作用,但它会激活Python的通用比较机制,这不是你想要的;如果x
是一个类的实例,则比较可能会引发异常。 is
简单快捷,只是进行身份测试 - 它不能超载。
同样,if x is True
的意思是“如果x是布尔对象,意思是真的,而根本没有其他对象” - 这可能很有用,但是当你只是测试真值时,它太窄了。有人可能最终传递1,这将失败'是真'测试,但其他行为非常像真。
行为与语言略有不同。
行为1:变量转换为布尔值。即有不同类型的语言特定转换为布尔值。对于数值,0
通常转换为false
,而任何其他值转换为true
。据我所知,这是Python的方式。
行为2:布尔值是数值。如上所述,0
通常是评估false
的唯一值
行为3:任何非空引用的计算结果为true
,null引用计算结果为false
。
这应该或多或少地覆盖它,但也可能存在其他变化或组合,例如,如果1不可用则使用回退到方法2或3。关键是这是一个特定于语言的问题。
变量的值被转换为布尔值,即执行type coercion。这究竟如何发生取决于语言。例如,在Python中,空列表的计算结果为false
。在大多数语言中,0
评估false
和true
的任何其他数字。
那么当然变量可能已经包含一个布尔值,例如
inBounds = day > 0 and day <= 31
if inBounds:
#...
已经有很多答案已经在“编程中的if
做什么”的总称中说,所以让我为你煮出你的代码。
def valid_day(day):
if day and day.isdigit():#if day
if
表示if
区块的开始,并且正如其他答案所指出的那样起作用。接下来是布尔表达式day and day.isdigit()
。 and
是一个布尔运算符,它需要两个操作数(方程式的两边,用外行的术语)为True
才能评估为True。在这种情况下,day
和day.isdigit()
都必须评估True
才能运行if
。
在Python中,我们将事物视为“Truthy”和“Falsey”。用“Falsey”来定义“Truthy”更容易,因为后者是一个更短的列表:
None
其他一切都是“Truthy”。如果你键入while -1: print("This loops forever")
,它实际上将永远循环。所有非零数字,所有非空容器(字符串,列表,dicts,集合,元组等),未明确设置为False
或None
的任何内容都将评估为True
。在这种情况下,代码检查以确保day
不是None
,因为如果是,那么day.isdigit()
将抛出AttributeError
并打破代码。您可以自己尝试:在IDLE中键入None.isdigit()
。请注意,这可能不是最简单的实现,因为做valid_day(31)
也会抛出AttributeError
。 valid_day
需要一个字符串,即使它正在检查数字。
day = int(day)
if day > 0 and day <= 31:
return day
这实际上是重复的代码,因为做int(day)
确认day.isdigit()
。如果这是你的代码,也许可以考虑一下try:except block,例如:
def valid_day(day):
try: int(day)
except ValueError as e:
return False #this means whatever you passed to it can't be converted
#into an integer: maybe a floating point string?
if day in range(1,32): return True
else: return False
这样可以避免检查您知道可能失败的所有内容的陷阱。相反,请检查以确保您的检查能够运行,并让您的程序处理您传递给它的任何内容。这也允许你设计一个包含更多信息而不是整数的Day
类,但仍然会使用self.__int__(): return self.calendarday
返回其日历日,而valid_day(Day())
将返回True。此外,当你应该返回None
时,你当前的代码会返回False
- 正如我上面提到的,None
是Falsey,因此在大多数情况下这将起作用(例如if not valid_day: do_something_drastic()
)但在某些情况下你可能想直接处理一个布尔值。
好的,对你来说有一句话。
TL; DR:if
启动if
块,day and day.isdigit()
只有当day是包含整数的非空字符串时才为真,其余的就是它所说的。
if day:
是写if day == True:
的简短方法。当它评估True == day
的结果时,如果day是一个简单的基本对象,如整数,那么Python解释器将尝试调用内置值比较。如果day是一个类,则解释器将调用其__nonzero__
成员函数。
例如
class MyClass:
def __nonzero__(self):
return False
if __name__ == "__main__":
c = MyClass()
if c:
print "yes"
else:
print "No"
正如其他人已经提供了解释,我只是举一些例子来说清楚。
# bool('') is False
if not '':
print('Empty String')
# bool([]) is False
if not []:
print('Empty list')
# bool(None) is False
if not None:
print('None type')
# bool(0) is False
if not 0:
print('Zero Value')
我认为在python中if条件有两个不同的检查。
现在的情况也是第二种风格。它正在检查day
是否是None
(毫无意义,null
)。
那么你的代码相当于
def valid_day(day):
if day is not None and day.isdigit():#if day
day = int(day)
if day > 0 and day <= 31:
return day
这也是一个强制性的检查,以避免Null access exception
,因为如果某个对象是None
的方式,如果我们试图访问一些方法,因为预期它不是None
,它将抛出异常。