在Python中初始化字符串变量:“”或“无”?


75

假设我有一个带有字符串实例属性的类。我应该使用“”值或初始化该属性吗?可以吗?

def __init__(self, mystr="")
   self.mystr = mystr

要么

def __init__(self, mystr=None)
   self.mystr = mystr

编辑:我想的是,如果我使用“”作为初始值,则将声明字符串类型的变量。然后,我以后将无法为其分配任何其他类型。我对吗?

编辑:我认为在这里要注意很重要,我的建议是错误的。并且将其他类型分配给变量没有问题。我喜欢S.Lott的评论:“由于“声明” Python中没有任何内容,因此您没有考虑正确的方法。


6
由于在Python中没有“声明”任何内容,因此您没有考虑正确的方法。
S.Lott

Answers:


82

如果没有值在程序中具有含义(例如,可选值),则应使用“无”。无论如何,这就是它的目的。

如果该值必须由__init__的调用者提供,则建议不要初始化它。

如果将“”作为默认值有意义,请使用它。

在Python中,类型是根据用法推导出来的。因此,您可以通过分配其他类型的值来更改类型。

>>> x = None
>>> print type(x)
<type 'NoneType'>
>>> x = "text"
>>> print type(x)
<type 'str'>
>>> x = 42
>>> print type(x)
<type 'int'>

4
+1:无或是什么意思""?设计选择完全取决于哪个值更有意义。
S.Lott

在上面的示例中,x的“类型”没有更改。相反,您有3个不同类型的对象:>>> x =无>>> id(x)1461526688 >>> x =“文本” >>> id(x)2520221413080 >>> x = 42 >>> id (x)1461692432而是将标签x绕三个对象移动。
DocOc

14

无用于表示“未设置”,而任何其他值用于表示“默认”值。

因此,如果您的类处理空字符串,并且您希望将其作为默认值,请使用“”。如果您的班级需要检查变量是否全部设置,请使用None。

请注意,变量最初是否为字符串都没有关系。您可以随时将其更改为任何其他类型/值。


12

初始化空字符串的另一种方法是使用str()不带参数的内置函数。

str(对象='')

返回一个字符串,其中包含对象的可很好打印的表示形式。

...

如果未提供任何参数,则返回空字符串“”。

在原始示例中,将如下所示:

def __init__(self, mystr=str())
   self.mystr = mystr

我个人认为,这可以更好地传达您的意图。

请注意,它str()本身将默认参数值设置为''


1
对于不可变类型,其结果与'',0,False,()相同。对于可变类型是即使如此糟糕,因为[] {}集()等,因为默认情况下该初始化函数被调用一次,并将结果用于_ init_反复..
hynekcer

5

这取决于。如果要区分根本不传入任何参数和传入的空字符串,则可以使用“无”。


5

要么可能被罚款,但我不认为这是一个肯定的答案。

  • 如果您要指示尚未设置该值,则与None进行比较要比与进行比较"",因为它""可能是有效值,
  • 如果您只想使用默认值,""可能会更好,因为它实际上是一个字符串,您可以在其上调用字符串方法。如果使用None,则会导致异常。
  • 如果您希望在将来向维护者表明需要字符串,则""可以提供帮助。

完整的旁注:

如果有循环,请说:

def myfunc (self, mystr = ""):
    for other in self.strs:
        mystr = self.otherfunc (mystr, other)

那么潜在的未来优化器将知道这str始终是字符串。如果您使用None,那么在第一次迭代之前它可能不是字符串,这需要循环展开才能获得相同的效果。尽管这不是一个假设(在我的PHP编译器中经常出现),但您绝对不应编写代码来考虑这一点。我只是认为这可能很有趣:)


好的注释,但您应避免将其str用作变量名,因为它会掩盖内置str()函数。
丹尼尔·罗斯曼

3

两者都不错,尽管None作为约定更常见-None表示没有为可选参数传递任何值。

这里是时候“”是正确的默认值来使用-在我的经验,不经常发生的时间。


1

由于None和“”均为假,因此您可以同时执行。参见6.1。真值测试

编辑

要在编辑中回答问题:否,您可以分配其他类型。

>>> a = ""
>>> type(a)
<type 'str'>
>>> a = 1
>>> type(a)
<type 'int'>

3
好吧,如果他检查真相,那么他会想念那""可能是有效值。更好的是,他None改为检查身体。
Paul Biggar

由于我们不知道OP正在检查什么,因此您和我都无法判断哪个对他更好。顺便说一句,当您对我的回答投了反对票时,您是否认为我的标记清晰的编辑可以回答OP编辑?

1

对于列表或字典,根据http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#default-parameter-values 使用None作为默认参数,答案更加明确。

但是对于字符串,在运行时还可以为关键字参数实例化一个(空)字符串对象。

最干净的方法可能是:

def myfunc(self, my_string=None):
    self.my_string = my_string or "" # or a if-else-branch, ...

4
为什么?这就是默认参数的工作,那么为什么要两次呢?为何不明确指定默认值呢?而且,另外,“”很明显地声明该函数需要一个字符串,None但不会告诉您。
u0b34a0f6ae

1

两种方法在python中都可以。我个人更喜欢“”。但同样,任何一种方式都可以

>>>x = None
>>>print(x)
None
>>>type(x)
<class 'NoneType'>
>>>x = "hello there"
>>>print(x)
hello there
>>>type(x)
<class 'str'>
>>> 
>>>x = ""
>>>print(x)

>>>type(x)
<class 'str'>
>>>x = "hello there"
>>>type(x)
<class 'str'>
>>>print(x)
hello there

1

Python哲学是可读的。
这就是为什么__init__()即使定义可选属性也是一种好的习惯。
本着同样的精神,您必须问自己,对于阅读您的代码的人来说,哪种方法更清晰。实际上,类型本身提供了有关变量将来使用的许多信息。所以:

kind = None

从语法上讲是正确的,但是读者了解的并不多。它是字符串,整数代码还是列表等?

kind_str = None
kind = ""

两者都说了一点,第一个在名称中具有类型,第二个在其声明中。我将第二次整理。


0
empty_string = ""

if not empty_string:

    print "Empty string is not set"

=>未设置空字符串

if empty_string is not None:
    print "Empty string is not None"

=>空字符串不是None

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.