python中的“if var”是啥意思?
Posted
技术标签:
【中文标题】python中的“if var”是啥意思?【英文标题】:What does "if var" mean in python?python中的“if var”是什么意思? 【发布时间】:2014-01-15 13:27:15 【问题描述】:这是python中用于验证日期条目的函数。
def valid_day(day):
if day and day.isdigit():#if day
day = int(day)
if day > 0 and day <= 31:
return day
我想知道表达式if day
是什么意思(就语义而言)。
我只知道if
对布尔表达式的影响,而不是对整数或数组等变量的影响。
【问题讨论】:
FWIW,您提供的函数 可以 记录为:“'day' 应为无,或可能为空的数字字符串;结果将为整数在 1..31 范围内(如果可以进行转换)或在其他情况下为无”。 一个小补充。最后一个条件可以写成if 0 < day <= 31
。
当我们挑选这些细节时 - 我会把它写成 1
【参考方案1】:
在python中,写
if var:
和写的效果一样
if bool(var):
(其中bool
是内置的bool
类型,它也充当布尔对象的构造函数)。
如果该值已经是布尔值(值为 True 或 False),则含义很明确—— bool(var) 返回相同的值。对于其他类型,几乎总是会转换为 bool available ,这取决于类型。对于整数(如在 C 中),它与 var!=0; 相同。对于列表、字典或字符串,它与 len(var)!=0 相同,依此类推。你可以在 python 文档中找到它。
当您定义自己的类时,您可以通过 def __nonzero__(self):
定义一个方法,该方法将在此上下文中调用(当您的对象显式传递给 bool
时,或隐式传递给 if
-- 或 @987654328 @就此而言)。
一个值得注意的例外: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 是否指代该对象,并且总是给您一个布尔值(如果是,则为 True,任何其他对象为 False)。比较x==None
(我开始使用 Python 时经常犯的一个错误)通常会起作用,但它会激活 Python 的通用比较机制,这可能不是您想要的;如果x
是类的实例,则比较可能会引发异常。 is
简单快捷,只进行身份测试 - 它不能超载。
同样if x is True
的意思是“如果 x 是布尔对象,表示为真,而根本没有其他对象”——这可能很有用,但对于仅测试真值的情况来说太窄了。有人可能最终通过了 1,这将无法通过“是真”测试,但在其他方面表现得非常像真。
【讨论】:
我注意到许多程序员倾向于有一种“拒绝”布尔表达式的风格。他们写if(boolvar==true)
(我现在在C++中),更糟糕的是if(x<0)is_neg = true; else isneg=false;
我不确定他们是否不知道它可以更简单,或者他们只是更喜欢它更复杂。或者也许这是从其他语言(fortran?matlab?)中学到的一种风格,您必须在其中做这些事情?
这看起来是检查对象是否为 None 的完美方法,无需使用丑陋的语法 if var is None
,甚至最糟糕的 if var is not None
。
@Gojir4 有什么作用?我没有提出任何替代方案,事实上我反对var==None
。 var is None
有什么“丑陋”的地方,如果你想测试的话?
@greggo,与其说“var is None”难看,不如说忘记“is None”是一个容易犯的错误。因此,如果一个类型的名义上是整数(或布尔型)但也可能是无,那么最好实现__nonzero__
。
@KeithHanlan 我不确定你在说什么。 if var is None
测试 var
是否是 None
对象。省略is None
,您正在测试var
的真值,这是一个不同的操作。再多的实现__nonzero__
也无法改变这一点(您只能将类类型定义为它自己的真值)。【参考方案2】:
行为因语言而异。
行为 1:
变量被转换为布尔值。 IE。有从不同类型到布尔值的特定语言转换。对于数值,0
通常转换为false
,而任何其他值都转换为true
。据我所知,Python 就是这样做的。
行为 2:
布尔值是数值。如上所述,0
通常是唯一计算为 false
的值
行为 3:
任何非空引用的计算结果为true
,空引用的计算结果为false
。
这应该或多或少地涵盖它,但也可能存在其他变体或组合,例如,如果 1 不可用,则使用回退到方法 2 或 3。关键是这是一个非常特定于语言的问题。
【讨论】:
比这更复杂一些,例如''
、空列表和None
(以及其他)被评估为False。
“即有从不同类型到布尔值的特定语言转换。”涵盖了,不是吗?
很抱歉 - 我错过了你答案中的 for numeric values
部分 :)【参考方案3】:
关于“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 中,我们将事物视为“真”和“假”。用“Falsey”来定义“Truthy”更容易,因为后者的列表要短得多:
None
0
错误
[] "" () 等
其他一切都是“真实的”。如果你输入while -1: print("This loops forever")
,它实际上会永远循环。所有非零数字、所有非空容器(字符串、列表、字典、集合、元组等),任何未明确设置为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 块,例如:
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。此外,当您应该返回 False
时,您当前的代码返回 None
——正如我上面提到的,None
是 Falsey,所以在大多数情况下这会起作用(例如 if not valid_day: do_something_drastic()
)但在某些情况下你可能想直接处理布尔值。
好的,有话要给你。
TL;DR:if
启动 if
块,day and day.isdigit()
仅当 day 是包含整数的非空字符串时才为真,其余部分按照它所说的那样做。
【讨论】:
感谢 adsmith,您的回答加上其他人的回答和评论,让我了解“如果”应用于非布尔(显式)值是什么意思。我最近加入了这个社区,这里有“很多”信息和合作。再次感谢!【参考方案4】:变量的值被转换为布尔值,即执行type coercion。这究竟是如何发生的取决于语言。例如,在 Python 中,一个空列表的计算结果为 false
。在大多数语言中,0
计算结果为 false
,任何其他数字计算结果为 true
。
那么当然变量可能已经包含一个布尔值,例如
inBounds = day > 0 and day <= 31
if inBounds:
#...
【讨论】:
不。 0 计算为false
,其他任何数字计算为 true
。
这是Python与其他语言有些不同的地方;在 python 中,几乎任何东西都可以在这样的布尔上下文中使用。 “if foo:”表示“如果 foo 不为空”。
@dstromberg:这就是为什么我说“这究竟是如何发生的取决于语言。”
@dstromberg if foo:
在 Python 中 not 的意思是 if foo is not empty
。有多种方法可以将 foo 评估为 False - 请参阅此问题的其他答案。【参考方案5】:
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"
【讨论】:
不一样。假设天='星期五'。然后if day
将测试为真,if day == True
将测试为假;非空字符串具有“真”真值,但 all 在字符串和布尔值之间使用 == 比较会产生 False;没有字符串等于布尔值。
if day:
是写 if bool(day):
的简写方式,或者,如果您愿意(我非常不愿意)if bool(day)==True:
【参考方案6】:
由于其他人已经提供了解释,我只是举一些例子来说明清楚。
# 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')
【讨论】:
【参考方案7】:我认为在 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
,它将抛出异常。
【讨论】:
这不是真的。if day
在布尔上下文中评估 day
- 它与 None
无关。实际上这里它正在检查空字符串。
字符串是否包含isdigit()
方法?
是的。您可以轻松检查。
你为什么期望只有字符串作为参数传递给valid_day
?
这段代码不是我写的。如果例如传递了一个非零 int,将引发 AttributeError
。但是该函数显然需要字符串,否则它不会调用isdigit
。以上是关于python中的“if var”是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章
Python 中的 @withparser 方法是啥意思? [复制]
Python 中的 @ 和 lambda 是啥意思? [复制]