Python是否有类似空字符串变量的功能,您可以在其中执行以下操作:
if myString == string.empty:
无论如何,检查空字符串值最优雅的方法是什么?我发现每次检查空字符串的硬编码“”都不太好。
Python是否有类似空字符串变量的功能,您可以在其中执行以下操作:
if myString == string.empty:
无论如何,检查空字符串值最优雅的方法是什么?我发现每次检查空字符串的硬编码“”都不太好。
当前回答
我发现每次检查空字符串的硬编码(sic)“”都不太好。
清洁代码方法
这样做:foo==“”是非常糟糕的做法。“”是一个神奇的值。你不应该检查魔法值(更常见的是魔法数字)
您应该做的是与描述性变量名称进行比较。
描述性变量名称
人们可能认为“empty_string”是一个描述性变量名称。它不是。
在你去做empty_string=“”并认为你有一个很好的变量名来比较之前。这不是“描述性变量名”的意思。
一个好的描述性变量名是基于其上下文的。你必须考虑空字符串是什么。
它从哪里来。为什么在那里。为什么你需要检查它。
简单表单字段示例
您正在构建一个用户可以输入值的表单。你想检查用户是否写了什么。
一个好的变量名可能是not_fill_in
这使得代码非常可读
if formfields.name == not_filled_in:
raise ValueError("We need your name")
完整的CSV解析示例
您正在解析CSV文件,并希望将空字符串解析为None
(由于CSV完全基于文本,因此在不使用预定义关键字的情况下无法表示None)
一个好的变量名可能是CSV_NONE
如果您有一个新的CSV文件,该文件用“”以外的另一个字符串表示None,则可以轻松更改和调整代码
if csvfield == CSV_NONE:
csvfield = None
这段代码是否正确是没有问题的。很明显,它做了它应该做的事情。
将此与
if csvfield == EMPTY_STRING:
csvfield = None
这里的第一个问题是,为什么空字符串值得特殊处理?
这将告诉未来的编码器,空字符串应该始终被视为None。
这是因为它混合了业务逻辑(CSV值应该是None)和代码实现(我们实际比较的是什么)
这两者之间需要分开关注。
其他回答
我曾经写过类似于Bartek的答案和javascript的灵感:
def is_not_blank(s):
return bool(s and not s.isspace())
测试:
print is_not_blank("") # False
print is_not_blank(" ") # False
print is_not_blank("ok") # True
print is_not_blank(None) # False
PEP 8中“编程建议”部分:
对于序列(字符串、列表、元组),请使用空序列为false的事实。
因此,您应该使用:
if not some_string:
or:
if some_string:
为了澄清,如果序列为空或不为空,则在布尔上下文中将其求值为False或True。它们不等于False或True。
最清晰的方法是:
if s == "":
优点:
向编程器提供应为什么类型的附加指示。“”不是“硬编码”,它是一个神奇的值,比x==0更大。有些值是基本的,不需要命名常量;例如,x%2以检查偶数。不能错误地指示任何错误值(例如[])为空字符串。
考虑如何检查整数是否为0:
if x == 0:
人们当然不应该这样做:
if not x:
整数和字符串都是基元值类型。为什么要区别对待他们?
最优雅的方法可能是简单地检查它是真是假,例如:
if not my_string:
但是,您可能需要删除空白,因为:
>>> bool("")
False
>>> bool(" ")
True
>>> bool(" ".strip())
False
但是,您可能应该对此更加明确一点,除非您确定该字符串已通过某种验证,并且是可以通过这种方式测试的字符串。
唯一真正可靠的方法是:
if "".__eq__(myString):
所有其他解决方案都可能存在检查失败的问题和边缘情况。
如果myString是继承自str并重写__len__()方法的类的对象,则len(myString)==0可能失败。myString==“”和myString__如果myString重写__eq__()和__ne__(),则eq__(“”)可能失败。“”==如果myString重写__eq__(),myString也会被愚弄。myString是“”,“”是myString。如果myString实际上不是字符串而是字符串的子类(两者都将返回False),则它们都将失败。此外,由于它们是身份检查,所以它们工作的唯一原因是因为Python使用字符串池(也称为字符串互存),如果字符串被互存,则使用相同的字符串实例(请参见此处:为什么使用“==”或“is”比较字符串有时会产生不同的结果?)。“”从一开始就在CPython实习身份检查的一个大问题是,字符串实习(据我所知)没有标准化哪些字符串被实习。这意味着,理论上“”不是必需的,这取决于实现。此外,使用字符串进行比较通常是一个非常邪恶的陷阱,因为它有时会正常工作,但有时不会,因为字符串池遵循非常奇怪的规则。如果对象重写__bool__(),则依赖字符串的虚假性可能不起作用。
唯一不能被愚弄的方法就是开头提到的“”__eq__(myString)。由于它显式调用空字符串的__eq__()方法,因此不能通过重写myString中的任何方法来欺骗它,并且可以与str的子类一起工作。
这不仅是理论上的工作,实际上可能与实际使用相关,因为我以前见过框架和库将str子类化,并且使用myString is“”可能会返回错误的输出。
也就是说,在大多数情况下,所有提到的解决方案都能正常工作。这主要是学术工作。