最优雅的方法来检查Python中的字符串是否为空?

Joa*_*nge 1282 python string comparison-operators

Python是否有类似空字符串变量的地方,你可以这样做:

if myString == string.empty:
Run Code Online (Sandbox Code Playgroud)

无论如何,检查空字符串值的最优雅方法是什么?我""每次都发现硬编码检查空字符串不太好.

And*_*ark 1889

空字符串是"falsy",这意味着它们在布尔上下文中被视为false,因此您可以这样做:

if not myString:
Run Code Online (Sandbox Code Playgroud)

如果您知道您的变量是字符串,那么这是首选方法.如果您的变量也可以是其他类型,那么您应该使用myString == "".有关布尔上下文中为false的其他值,请参阅真值测试文档.

  • 要小心,因为很多其他事情也是假的. (155认同)
  • OP想要知道变量是否为空字符串,但是如果`myString`是`None`,`0`,`False`等,你也会输入`if not myString:`块.所以如果你不确定什么类型`myString`,你应该使用`if myString =="":`来确定它是否是一个空字符串而不是其他一些虚假值. (45认同)
  • @Joan:它在布尔上下文中计算为false. (37认同)
  • 我之前从未听说过falsy这个词.这是否意味着它返回false? (9认同)
  • @AndrewClark,对于这种情况,我们可以使用`if myString in(None,'')`或者@Bartek,如果myString in(None,),而不是`if myString == ...`表达式链. '')或不是myString.strip()` (9认同)
  • @Bartek的答案也应该考虑在内.今天受到这种打击,思考django形式所需的验证将注意空字符串,如"""`而不是. (3认同)
  • 检查Falsyness会导致错误.显式优于隐式,`the_string ==''更难以解释. (3认同)
  • 值得注意的是,如果该行显示为空白,但实际上包含换行符“\n”,则您可能会在“if string”上得到肯定的结果 (2认同)
  • 好吧,如果它*包含*换行符,那么它不是空的.制表符,空格和所有形式的不可打印字符也是如此. (2认同)

zen*_*poy 378

PEP 8开始,在"编程建议"部分中:

对于序列,(字符串,列表,元组),请使用空序列为假的事实.

所以你应该使用:

if not some_string:
Run Code Online (Sandbox Code Playgroud)

要么:

if some_string:
Run Code Online (Sandbox Code Playgroud)

只是为了澄清,序列评估FalseTrue在布尔上下文如果它们是空的或不是.他们不等于FalseTrue.

  • 很棒,你包括对PEP的参考! (19认同)
  • PS:在PEP的辩护中,人们可以争辩说"*x为假*"(小写*false*)已经意味着,而不是意味着"x == False".但恕我直言,鉴于目标受众,澄清仍然是受欢迎的. (3认同)

Bar*_*tek 213

最优雅的方式可能是简单地检查它是真的还是假的,例如:

if not my_string:
Run Code Online (Sandbox Code Playgroud)

但是,您可能希望剥离空格,因为:

 >>> bool("")
 False
 >>> bool("   ")
 True
 >>> bool("   ".strip())
 False
Run Code Online (Sandbox Code Playgroud)

你可能应该更明确一点,除非你确定这个字符串已经通过了某种验证,并且是一个可以通过这种方式测试的字符串.


rou*_*ble 77

我会在剥离之前测试一下.另外,我会使用空字符串为False(或Falsy)的事实.这种方法类似于Apache的StringUtils.isBlankGuava的Strings.isNullOrEmpty

这是我用来测试字符串是否为空或空或空白:

def isBlank (myString):
    if myString and myString.strip():
        #myString is not None AND myString is not empty or blank
        return False
    #myString is None OR myString is empty or blank
    return True
Run Code Online (Sandbox Code Playgroud)

并且,如果字符串不是测试则完全相反无NOR空NOR空白:

def isNotBlank (myString):
    if myString and myString.strip():
        #myString is not None AND myString is not empty or blank
        return True
    #myString is None OR myString is empty or blank
    return False
Run Code Online (Sandbox Code Playgroud)

以上代码的更简洁形式:

def isBlank (myString):
    return not (myString and myString.strip())

def isNotBlank (myString):
    return bool(myString and myString.strip())
Run Code Online (Sandbox Code Playgroud)

  • 关于这些事情的人更简洁:`def isBlank(s):return not(s和s.strip())`和`def isNotBlank(s):return s和s.strip()`. (6认同)
  • `s.strip()` 分配一个新字符串,这纯粹是浪费。使用 string.isspace() (5认同)
  • 它与 `string 而不是 string.isspace()` 有何不同? (2认同)
  • 这个答案不是很Pythonic (2认同)

vau*_*ult 42

我曾经写过一些类似于Bartek的回答和javascript的启发:

def is_not_blank(s):
    return bool(s and s.strip())
Run Code Online (Sandbox Code Playgroud)

测试:

print is_not_blank("")    # False
print is_not_blank("   ") # False
print is_not_blank("ok")  # True
print is_not_blank(None)  # False
Run Code Online (Sandbox Code Playgroud)

  • `s.strip()` 分配一个新字符串,这纯粹是浪费。使用 string.isspace() (5认同)

Dak*_*ron 17

唯一真正可靠的方法是:

if "".__eq__(myString):
Run Code Online (Sandbox Code Playgroud)

所有其他解决方案都可能存在问题,并且可能导致检查失败。

len(myString)==0如果myString是从str__len__()方法继承并覆盖该方法的类的对象,则该方法可能会失败。

同样myString == ""myString.__eq__("")如果myString覆盖__eq__()和,则可能失败__ne__()

由于某种原因,"" == myString如果myString覆盖也将被愚弄__eq__()

myString is """" is myString等价。如果它们myString实际上不是字符串而是字符串的子类,则它们都将失败(都将返回False)。另外,由于它们是身份检查,所以它们起作用的唯一原因是因为Python使用了String Pooling(也称为String Internment),该字符串池在被插入时使用相同的字符串实例(请参见此处:为什么使用'=来比较字符串='或'是否'有时会产生不同的结果?)。并""从一开始就在CPython中进行实习

身份检查的最大问题是,据我所知,String Internment不规范要插入哪些字符串。这意味着,理论上""没有必要进行实习,而依赖于实现。

真正不能被愚弄的唯一方法是开头提到的方法:"".__eq__(myString)。由于此__eq__()方法明确调用了空字符串的方法,因此不能通过覆盖myString中的任何方法来欺骗它,并且可以与的子类牢固地结合使用str

如果对象覆盖了它的__bool__()方法,那么依靠字符串的虚假性可能也不起作用。

这不仅是理论上的工作,而且实际上可能与实际用法有关,因为我之前看到过框架和库的子类化str,使用myString is ""那里可能会返回错误的输出。

而且,is通常使用字符串比较字符串是一个很糟糕的陷阱,因为它有时会正确运行,而在其他时候则无法正常工作,因为字符串池遵循非常奇怪的规则。

也就是说,在大多数情况下,所有提到的解决方案都可以正常工作。这是大多数学术工作。

  • @simpleuser你当然是对的。在现实世界中,使用字符串的错误或将其与空字符串进行比较是完全可以的。这里的答案是故意矫枉过正的。 (2认同)

小智 13

测试空或空字符串(更短的方式):

if myString.strip():
    print("it's not an empty or blank string")
else:
    print("it's an empty or blank string")
Run Code Online (Sandbox Code Playgroud)

  • 如果`myString = None`,它将引发异常.更好用@vault的[答案](http://stackoverflow.com/a/27982561/1168315) (5认同)

Sil*_*Ray 9

如果你想区分空字符串和空字符串,我建议使用if len(string),否则,我建议使用简单,if string就像其他人说的那样.关于充满空白字符串的警告仍然适用,所以不要忘记strip.


小智 7

a = ''
b = '   '
a.isspace() -> False
b.isspace() -> True
Run Code Online (Sandbox Code Playgroud)

  • 真的不明白这个解决方案有什么好处。问题是关于测试字符串是否为空。如果你设置 `a='a'` 你会得到 `a.isspace() -> False`,但是 `a` 不会是一个空字符串。 (3认同)

小智 7

如果你想检查一个字符串是否完全为空

if not mystring
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为空字符串是假的,但如果字符串只有空格,它将是真的,所以你可能想要

if not mystring.strip()
Run Code Online (Sandbox Code Playgroud)


Kak*_*shi 6

if stringname:false当字符串为空时给出一个.我想它不能比这更简单.


Buv*_*inJ 6

这个怎么样?也许它不是“最优雅的”,但它似乎非常完整和清晰:

if (s is None) or (str(s).strip()==""): // STRING s IS "EMPTY"...
Run Code Online (Sandbox Code Playgroud)

  • 对于大多数用途,包含空格的字符串不是“空”。 (2认同)

fir*_*ynx 6

每次检查空字符串时,我都发现用硬编码“”不好。

干净的代码方法

这样做:foo == ""是非常不好的做法。""是一个神奇的价值。您永远都不应检查魔术值(通常称为魔术数

您应该做的是与描述性变量名称进行比较。

描述性变量名称

可能会认为“ empty_string”是一种描述性变量名。不是

在去做之前,请empty_string = ""以为您有一个很好的变量名可以比较。这不是“描述性变量名”的含义。

一个好的描述性变量名称基于其上下文。你要想想空字符串什么

  • 它从何而来。
  • 为什么在那儿。
  • 为什么需要检查它。

简单表单字段示例

您正在构建一个表单,用户可以在其中输入值。您要检查用户是否写了什么。

一个好的变量名可能是 not_filled_in

这使得代码非常可读

if formfields.name == not_filled_in:
    raise ValueError("We need your name")
Run Code Online (Sandbox Code Playgroud)

全面的CSV解析示例

您正在解析CSV文件,并希望将空字符串解析为 None

(由于CSV完全基于文本,因此如果不None使用预定义的关键字就无法表示)

一个好的变量名可能是 CSV_NONE

如果您有一个新的CSV文件,该文件None用另一个字符串表示,则使代码易于更改和调整。""

if csvfield == CSV_NONE:
    csvfield = None
Run Code Online (Sandbox Code Playgroud)

毫无疑问,这段代码是否正确。很明显,它做了应该做的事情。

比较一下

if csvfield == EMPTY_STRING:
    csvfield = None
Run Code Online (Sandbox Code Playgroud)

这里的第一个问题是,为什么空字符串应该得到特殊对待?

这将告诉以后的编码人员,应该始终将空字符串视为None

这是因为它将业务逻辑(CSV值应为None)与代码实现(我们实际比较的是什么)混合在一起

两者之间需要分开关注

  • 真的需要费那么大的力气才能避免出现“”吗?在比较的上下文中,空白字符串还意味着什么? (5认同)
  • 你说“not_filled_in”比“empty_string”更具描述性?我说你高。 (2认同)
  • 我不同意这个答案。魔术数字不好,这是有道理的。魔术值也是如此。但是“””不是魔术值,与“ True”,“ False”或“ None”不是魔术值相同。 (2认同)
  • @firelynx 你能比使用“””更明确地说“这个字符串是空的”吗?您还会将“True”重新定义为“REALLY_TRUE”吗?最后你会得到很多表示相同内容的变量(与字面量“””相比,这些变量是非常量的)。那么,CSV_NONE 与 JSON_EMPTY_VALUE 不同吗?当您在程序的不同部分之间转移时,就会出现问题。那么你可能不再知道你是否有一个 `None` 或一个 `""`,特别是如果你将常量命名为像 `CSV_NONE` 之类的误导性名称,它实际上不是 `None` 而是 `""`。 (2认同)
  • @firelynx 这比仅使用常量值 `None`、`True`、`False` 或 `""` 会导致更多的歧义。每当您在名称中编码的信息多于值本身已有的信息时,使用变量而不是魔术值会很有用,例如使用“STATE_A”而不是“27”。或者每当有歧义时,例如“GPIO.HIGH”而不是“1”,因为根据您使用的逻辑,“1”可能是“HIGH”或“LOW”。但在给定的示例中,使用变量弊大于利。 (2认同)

Tom*_*ugh 5

我对 ''、' '、'\n' 等字符串做了一些实验。我希望 isNotWhitespace 为 True 当且仅当变量 foo 是一个至少包含一个非空白字符的字符串。我正在使用Python 3.6。这就是我最终得到的结果:

isWhitespace = str is type(foo) and not foo.strip()
isNotWhitespace = str is type(foo) and not not foo.strip()
Run Code Online (Sandbox Code Playgroud)

如果需要,请将其包装在方法定义中。