142

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

我想知道None价值什么,你用它做什么?

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

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

这意味着什么?

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

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

最终的:

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

4

9 回答 9

112

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

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

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

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

F = "fork"

你把贴纸“F”放在一个字符串对象上"fork"。如果你再写

F = None

您将贴纸移到None对象上。

Briggs 要求你想象的是,你没有贴纸"F"已经F贴纸了None,你所做的只是它从移动None"fork"。因此,当您输入 时,如果我们决定将其视为含义F = None,您将“将其重置为原始的空状态” 。Noneempty 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"andA = 2和之类的线来写c17 = 3.14,然后你可以稍后将它们粘贴到其他对象上(比如F = 10or F = None;都是一样的.)

Briggs 假装您可能想写的所有可能的贴纸都已经粘在None物体上。

于 2013-10-20T05:29:23.600 回答
72

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 and null等。

请注意,在 Python 中,变量因被使用而存在。您不需要先声明变量,因此 Python 中没有真正的变量。将变量设置为None与将其设置为默认空值不同;None也是一个值,尽管它经常被用来表示空虚。您正在阅读的这本书在这一点上具有误导性。

于 2013-10-20T02:13:19.137 回答
26

这就是Python 文档必须说的None

types.NoneType 的唯一值。None 经常用于表示没有值,例如默认参数未传递给函数时。

在 2.4 版更改:对 None 的赋值是非法的并引发 SyntaxError。

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

  1. None我们先确认一下类型

    print type(None)
    print None.__class__
    

    输出

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

基本上,NoneType是一种类似于int,float等的数据类型。您可以查看 Python 8.15 中可用的默认类型列表。types - 内置类型的名称

  1. 并且,NoneNoneType类的一个实例。所以我们可能想创建None自己的实例。让我们试试

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

    输出

    0
    TypeError: cannot create 'NoneType' instances
    

很明显,不能创建NoneType实例。我们不必担心 value 的唯一性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:)

于 2013-10-20T03:34:34.330 回答
11

您所指的这本书显然是在试图大大简化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

哎呀!

所以这本书在使用“ reset ”这个词时有点误导——给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
于 2013-10-20T20:15:43.463 回答
6

其他答案已经很好地解释了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 时随后使用相同的列表。这是因为默认参数中的表达式是在定义函数时计算的,而不是在调用它时计算的

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


'None' 救世主:(修改上面的示例以产生所需的行为)

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 的示例信用

于 2017-07-04T22:40:31.640 回答
3

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


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

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

于 2015-06-05T07:16:51.543 回答
3

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

想象一下,您为婚礼收集回复。您想记录每个人是否会参加。如果他们参加,您设置person.attending = True. 如果他们不参加你的设置person.attending = False。如果您还没有收到任何回复,那么person.attending = None. 这样您就可以区分没有信息None- 和否定答案。

于 2020-02-26T09:52:16.767 回答
1

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

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

None 没有任何意义,它没有任何价值。

无评估为 False。

于 2013-10-20T02:15:34.627 回答
-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 
于 2016-12-07T02:59:15.113 回答