什么是无值?


130

我一直在研究Python,并且阅读了一章描述了它的None价值,但不幸的是,这本书在某些方面并不十分清楚。我认为,如果我在那分享我的问题,我会找到答案。

我想知道None价值什么,您将其用于什么?

而且,我没有得到本书的这一部分:

将值None赋给变量是将其重置为其原始的空状态的一种方法。

那是什么意思?

答案很棒,尽管由于我对计算机世界的了解不足(我还没有了解类,对象等),所以我对大多数答案都不了解。这句话是什么意思?

将值None赋给变量是将其重置为其原始的空状态的一种方法。

最后:

最后,我从寻找不同的答案中得到了答案。我必须感谢所有抽出宝贵时间来帮助我的人(尤其是Martijn Pieters和DSM),我希望我可以选择所有答案作为最佳答案,但是选择仅限于一个。所有的答案都很好。


39
那本书不太有用。None不是变量的默认空状态。
马丁·彼得斯

php是唯一一种空值等于变量的默认空状态的语言。现在,我想知道还有哪些其他语言可以做到这一点。
2013年

@kojiro perl,尽管两个相等运算符都不愿意与比较undef。也可以说是javascript,尽管它同时具有nullundefined
伊夫2013年

undefined如果未初始化,则@kojiro javascript变量的默认值为。
thefourtheye

对了,这是不同null,这一点我没有作出对他的回答@MartijnPieters。
2013年

Answers:


99

Martijn的答案解释了NonePython中的内容,并正确指出该书具有误导性。由于Python程序员通常不会说

将值None赋给变量是将其重置为其原始的空状态的一种方法。

很难以一种有意义的方式来解释布里格斯的意思,并解释为什么这里没有人对此感到满意。一个类推可能会有所帮助:

在Python中,变量名称就像贴在对象上的标签。每个标签上都有一个唯一的名称,并且一次只能在一个对象上,但是如果需要,您可以在同一对象上放置多个标签。当你写

F = "fork"

您将标签“ F”放在字符串对象上"fork"。如果你再写

F = None

您将标签移动到None对象。

Briggs想让您想象的是,您没有贴纸"F",但已经F贴纸上了None,您所做的就是其从None移到"fork"。因此F = None,如果我们决定将其None视为,则在键入时,您会将其“重置为原始的空状态” empty state

我可以看到他的意思,但这是一种不好的观察方式。如果启动Python并输入print(F),则会看到

>>> print(F)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'F' is not defined

NameError意味着Python无法识别这个名字F因为没有这样的标签。如果Briggs是正确的并且F = None重置F为原始状态,那么它应该现在在那里,并且我们应该看到

>>> print(F)
None

就像我们在键入F = None并贴上贴纸后所做的一样None


这就是所有的事情。实际上,Python附带了一些已经粘贴到对象上的标签(内置名称),但是其他一些标签则需要使用诸如F = "fork"and A = 2和这样的行来编写c17 = 3.14,然后再将其粘贴在其他对象上(例如F = 10or F = None;它们都是一样的) )

Briggs假装您可能要写的所有可能的贴纸均已粘贴到该None对象上。


1
抱歉,您所说的布里格斯是什么意思?您指的是这本书的作者吗?因为他叫Jason R. Briggs。
The_Diver

@The_Diver:是的,就是他。
DSM 2013年

在哪里可以找到有关Python内置名称的更多信息?
The_Diver 2013年

3
对于非程序员,这是一个很好的解释。非常感谢你!
克里斯蒂娜

67

None只是通常用于表示“空”或“此处无值”的值。它是一个信号对象 ; 它仅具有含义,因为Python文档说明了它的含义。

在给定的Python解释器会话中,该对象只有一个副本。

例如,如果您编写一个函数,但该函数不使用显式return语句,None则返回该函数。这样,使用函数进行编程就大大简化了;一个函数总是返回某些东西,即使它只是那个None对象。

您可以明确地对其进行测试:

if foo is None:
    # foo is set to None

if bar is not None:
    # bar is set to something *other* than None

另一个用途是为函数提供可选参数,默认为“空”:

def spam(foo=None):
    if foo is not None:
        # foo was specified, do something clever!

该函数spam()有一个可选参数。如果在spam()未指定的情况下进行调用,则会为其指定默认值None,从而易于检测是否使用参数调用了该函数。

其他语言也有类似的概念。SQL有NULL; JavaScript具有undefined null,等等。

请注意,在Python中,变量通过使用而存在。您无需先声明变量,因此Python 中没有真正的变量。那么,将变量设置None为与将其设置为默认的空值是不同的。None也是一个值,尽管该值通常用于表示空白。您正在阅读的书在这一点上具有误导性。


1
我认为空虚的语义不同于未定义的语义。因此,我不确定JavaScript和SQL对应对象是否正在澄清-它们可能会使问题混淆。JavaScript同时具有undefined null
2013年

@kojiro:undefined是JavaScript中的一个对象,您可以像None在Python中一样显式地使用该对象。它是一个信号对象,含义大致相同。
马丁·彼得斯

@kojiro:SQL不是一种编程语言,但NULL仍然可以明确地分配和测试。
的Martijn Pieters的

5
@MartijnPieters:SQL 一种编程语言,只是一种非常特定的目的,即声明性的一种。
danielkza

3
@daniel:羯羊SQL资格作为一种编程语言已经有很长的辩论...查看stackoverflow.com/questions/900055/...有趣的角度。
马丁·彼得斯

23

这就是Python文档必须说的None

types.NoneType的唯一值。当没有将默认参数传递给函数时,通常不使用None来表示缺少值。

在版本2.4中更改:分配为None是非法的,并引发SyntaxError。

注意不能重新分配名称None和debug(分配给它们,即使作为属性名称,也会引发SyntaxError),因此可以将它们视为“ true”常量。

  1. 让我们确认None第一个的类型

    print type(None)
    print None.__class__
    

    输出量

    <type 'NoneType'>
    <type 'NoneType'>
    

基本上,NoneType数据类型与intfloat等类似。您可以在8.15中查看Python中可用的默认类型列表types —内置类型的名称

  1. 并且,NoneNoneType类的实例。因此,我们可能要创建None自己的实例。让我们尝试一下

    print types.IntType()
    print types.NoneType()
    

    输出量

    0
    TypeError: cannot create 'NoneType' instances
    

很明显,无法创建NoneType实例。我们不必担心价值的独特性None

  1. 让我们检查一下我们是如何None内部实现的。

    print dir(None)

    输出量

    ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', 
     '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
     '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
    

除了__setattr__,所有其他均为只读属性。因此,我们无法更改的属性None

  1. 让我们尝试为添加新属性 None

    setattr(types.NoneType, 'somefield', 'somevalue')
    setattr(None, 'somefield', 'somevalue')
    None.somefield = 'somevalue'
    

    输出量

    TypeError: can't set attributes of built-in/extension type 'NoneType'
    AttributeError: 'NoneType' object has no attribute 'somefield'
    AttributeError: 'NoneType' object has no attribute 'somefield'
    

上面看到的语句分别产生这些错误消息。这意味着,我们不能在None实例上动态创建属性。

  1. 让我们检查一下分配东西时会发生什么None。根据文档,它应该抛出SyntaxError。这意味着,如果我们向分配了某些内容None,则该程序将根本不会执行。

    None = 1

    输出量

    SyntaxError: cannot assign to None

我们已经确定

  1. None 是...的实例 NoneType
  2. None 不能有新属性
  3. 的现有属性None无法更改。
  4. 我们无法创建的其他实例 NoneType
  5. 我们甚至不能通过None给它分配值来更改对它的引用。

因此,如文档中所述,None实际上可以将其视为true constant

很高兴知道None:)


非常非常有趣!一个怀疑的是使用的__setattr__为无
Grijesh肖汉

9

您所指的书显然是试图大大简化的含义None。Python的变量不具备初始,空状态- Python的变量绑定(只),他们定义的时候。如果不给它一个值,就不能创建一个Python变量。

>>> print(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> def test(x):
...   print(x)
... 
>>> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() takes exactly 1 argument (0 given)
>>> def test():
...   print(x)
... 
>>> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test
NameError: global name 'x' is not defined

但是有时候您想让一个函数根据变量是否定义而具有不同的含义。您可以创建默认值为的参数None

>>> def test(x=None):
...   if x is None:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

None在这种情况下,此值是特殊值并不十分重要。我可以使用任何默认值:

>>> def test(x=-1):
...   if x == -1:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

…但是None到处都有给我们带来两个好处:

  1. 我们不必选择-1含义不明确的特殊值,并且
  2. 实际上,我们的函数可能需要-1作为普通输入处理。
>>> test(-1)
no x here

哎呀!

因此,这本书在使用“ 重设 ”一词时通常会产生一些误导–分配None名称是向程序员发出信号,表明该值未在使用中,或者该函数应以某种默认方式运行,但需要重设一个值要恢复其原始的未定义状态,您必须使用del关键字:

>>> x = 3
>>> x
3
>>> del x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

5

其他答案已经很好地解释了None的含义。但是,我仍然想通过一个例子对此进行更多说明。

例:

def extendList(val, list=[]):
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

现在尝试猜测上面列表的输出。好吧,答案令人惊讶地如下:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

但为什么?

许多人会错误地期望list1等于[10]list3等于['a'],以为每次调用extendList时,list参数将被设置为其默认值[]

但是,实际发生的情况是,在定义函数时,仅会创建一次新的默认列表,然后在每次调用extendList且未指定list参数的情况下都使用同一列表。这是因为默认参数中的表达式是在定义函数时计算的,而不是在调用函数时计算的

因此,list1list3在同一默认列表上运行,而list2在它创建的单独列表上运行(通过传递其自己的空列表作为list参数的值)。


“无”救星:(修改上面的示例以产生所需的行为)

def extendList(val, list=None):
    if list is None:
       list = []
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

使用此修订的实现,输出将是:

list1 = [10]
list2 = [123]
list3 = ['a']

注意 -贷记至toptal.com的示例


3

None是一个单例对象(意味着只有一个None),在语言和库中的许多地方都用于表示缺少其他值。


例如:
if d是一个字典,如果存在d.get(k)则返回d[k],但None如果d没有key 则返回k

从一个很棒的博客中阅读以下信息:http : //python-history.blogspot.in/


3

所有这些都是很好的答案,但是我认为还有更多的原因可以解释None

想象一下,您在婚礼上收集了RSVP。您想记录每个人是否参加。如果他们正在参加,请设置person.attending = True。如果他们不参加,您设置person.attending = False。如果尚未收到任何RSVP,则person.attending = None。这样,您可以区分无信息None和否定答案。


1

我喜欢代码示例(以及水果),所以让我告诉你

apple = "apple"
print(apple)
>>> apple
apple = None
print(apple)
>>> None

没有意味着什么,没有价值。

没有一个计算结果为False。


8
print(None)打印.. None。它不是,正如你提到的,打印什么。
马丁·彼得斯

如果REPL None是最后一个表达式的结果,则REPL仅显示任何内容。(这对不打算返回值的函数很有用。)
Eevee 2013年

Eugh,我的错误,我使用的是IDLE,并且假定它打印了变量,显然它使用了repl。我目前正在使用SO来完善我自己的python / javascript / code阅读和理解技能,所以我犯了一些错误:(
Azeirah 2013年

2
像Python交互式解释器提示一样,IDLE显式隐藏( None如果这是表达式的结果),主要是为了不使输出混乱。
马丁·彼得斯

-5
largest=none
smallest =none 
While True :
          num =raw_input ('enter a number ') 
          if num =="done ": break 
          try :
           inp =int (inp) 
          except:
              Print'Invalid input' 
           if largest is none :
               largest=inp
           elif inp>largest:
                largest =none 
           print 'maximum', largest

          if smallest is none:
               smallest =none
          elif inp<smallest :
               smallest =inp
          print 'minimum', smallest 

print 'maximum, minimum, largest, smallest 
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.