什么是“无”值?

我一直在学习 Python,我读了一章描述 None值,但不幸的是,这本书在某些方面不是很清楚。我以为我会找到问题的答案,如果我在那里分享的话。

我想知道什么 None和你用它来做什么?

还有,我不明白这部分:

None值赋给变量是将其重置为 它原来的空状态。

那是什么意思?

答案是伟大的,虽然我不明白的答案,由于我对计算机世界的知识很少(我没有学习类,对象等)。这句话是什么意思?

None值赋给变量是重置变量的一种方法 回到原来的空虚状态。

决赛:

最后我通过寻找不同的答案得到了我的答案。我必须感谢所有投入时间来帮助我的人(特别是马丁 · 彼得斯和 DSM) ,我希望我可以选择所有的答案作为最好的,但选择仅限于一个。所有的答案都很棒。

213600 次浏览

None只是一个通常用来表示“ em pty”或“ no value here”的值。它是 信号物体; 它之所以有意义,是因为 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

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

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

函数 spam()有一个可选的参数; 如果您调用 spam()而没有指定它,那么就会给它默认值 None,这样就很容易检测到函数是否是用参数调用的。

其他语言也有类似的概念: SQL 有 NULL,JavaScript 有 ABC1 < em > 及 null,等等。

请注意,在 Python 中,变量的存在是由于使用。您不需要首先声明一个变量,因此在 Python 中没有真正的 空荡荡的变量。然后,将变量设置为 None与将其设置为默认空值不是一回事; None也是一个值,尽管它经常用于 信号空值。你正在读的那本书在这一点上有误导性。

我喜欢代码示例(以及水果) ,所以让我向您展示一下

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

毫无意义,毫无价值。

没有一个计算结果为 False。

这就是 Python 文档None的评价:

类型的唯一值。经常用于表示 缺少值,例如当没有将默认参数传递给 功能。

在版本2.4中更改: 赋值为无是非法的,并引发 语法错误。

注意: 无法重新分配“无”和“ 调试”的名称(分配到 即使作为属性名称,也会引发 SyntaxError) ,因此它们可以 被认为是“真”的常量。

  1. 让我们先确认 None的类型

    print type(None)
    print None.__class__
    

    输出

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

Basically, NoneType is a data type just like int, float, etc. You can check out the list of default types available in Python in 8.15. types — Names for built-in types.

  1. And, None is an instance of NoneType class. So we might want to create instances of None ourselves. Let's try that

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

    输出

    0
    TypeError: cannot create 'NoneType' instances
    

So clearly, cannot create NoneType instances. We don't have to worry about the uniqueness of the value None.

  1. Let's check how we have implemented None internally.

    print dir(None)
    

    输出

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

Except __setattr__, all others are read-only attributes. So, there is no way we can alter the attributes of None.

  1. Let's try and add new attributes to 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'
    

The above seen statements produce these error messages, respectively. It means that, we cannot create attributes dynamically on a None instance.

  1. Let us check what happens when we assign something None. As per the documentation, it should throw a SyntaxError. It means, if we assign something to None, the program will not be executed at all.

    None = 1
    

    输出

    SyntaxError: cannot assign to None
    

We have established that

  1. None is an instance of NoneType
  2. None cannot have new attributes
  3. Existing attributes of None cannot be changed.
  4. We cannot create other instances of NoneType
  5. We cannot even change the reference to None by assigning values to it.

So, as mentioned in the documentation, None can really be considered as a true constant.

Happy knowing None :)

Martijn 的回答解释了 Python 中的 None是什么,并且正确地指出这本书是误导性的。因为 Python 程序员一般不会说

None值赋给变量是将其重置为 它原来的空状态。

很难用合理的方式解释布里格斯的意思,也很难解释为什么这里没有人对此感到满意。一个类比可能有所帮助:

在 Python 中,变量名就像贴在对象上的贴纸。每个贴纸上都有一个独一无二的名字,而且一次只能贴在一个物体上,但是如果你想的话,你可以在同一个物体上贴不止一个贴纸。当你写作的时候

F = "fork"

在字符串对象 "fork"上贴上“ F”

F = None

你把贴纸移到 None对象上。

布里格斯想让你想象的是,你没有 写作的标签 "F",有 已经F的标签 None,你所做的就是 F0它,从 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因为根本就没有这样的标签这个名字。如果布里格斯是正确的,F = None重置 F到它的原始状态,那么它现在应该在那里,我们应该看到

>>> print(F)
None

就像我们输入 F = None并把标签贴在 None上之后做的那样。


事情就是这样。实际上,Python 有一些已经贴在对象上的标签(内置名称) ,但是其他的你必须用像 F = "fork"A = 2c17 = 3.14这样的行来写你自己,然后你可以把它们贴在其他对象上(像 F = 10F = None; 都是一样的)

Briggs 假装所有你可能想要写的贴纸都已经粘在 None对象上了。

你提到的这本书显然是在试图简化 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

None 是一个单例对象(意味着只有一个 Nothing) ,在 表示某种价值的缺失的语言和库的许多地方使用。


例如: < br > 如果 d是一个字典,d.get(k)将返回 d[k](如果它存在) ,但是如果 d没有键 k,则返回 None

阅读这个信息从一个伟大的博客: https://python-history.blogspot.com/2013/11/story-of-none-true-false.html

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

其他的答案已经很好地解释了 的含义。然而,我还是想用一个例子来阐明这一点。

例如:

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']

但是为什么?

许多人会错误地认为 清单1等于 [10],而 清单3等于 [‘ a’],认为每次调用 extendList 时,list 参数都会被设置为其默认值 []

但是,实际发生的情况是 新的默认列表只在定义函数时创建一次和相同的列表随后在不指定列表参数的情况下调用 extList 时使用。这是因为 默认参数中的表达式是在定义函数时计算的,而不是在调用函数时计算的

因此,list1 清单3在相同的默认列表上运行,而 清单2在它创建的单独列表上运行(通过传递它自己的空列表作为列表参数的值)。


“无”救世主: (修改上面的例子以产生期望的行为)

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 的贷款实例

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

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