我一直在研究Python,我读了一章描述了None
的值,但遗憾的是这本书在某些方面并不是很清楚。如果我在那里分享,我想我会找到问题的答案。
我想知道None
值是是什么,你用它做什么?
而且,我没有得到这本书的这一部分:
为变量赋值
None
是将其重置为的一种方法 原来的空虚状态。
这是什么意思?
答案很棒,但由于我对计算机世界的了解不足(我还没有学过课程,对象等),所以我不理解大部分答案。这句话是什么意思?
为变量赋值
None
是重置变量的一种方法 到原来的空虚状态。
决赛:
最后,我从不同的答案中得到了答案。我必须感谢那些把时间用来帮助我的人(特别是Martijn Pieters和DSM),我希望我能选择所有答案作为最佳答案,但选择仅限于一个。所有答案都很棒。
答案 0 :(得分:81)
Martijn的回答解释了Python中None
的含义,并正确地指出该书具有误导性。因为Python程序员通常不会说
为变量赋值
None
是将其重置为的一种方法 原来的空虚状态。
很难用一种有意义的方式解释布里格斯的意思,并解释为什么这里没有人对它感到满意。一个可能有用的类比:
在Python中,变量名称就像贴在物体上的贴纸一样。每个贴纸都有一个独特的名字写在上面,它一次只能放在一个物体上,但如果你愿意的话,可以在同一个物体上放一个以上的贴纸。当你写
F = "fork"
您将标签“F”放在字符串对象"fork"
上。如果你再写
F = None
将贴纸移动到None
对象。
布里格斯要求你想象的是,你没有写标签"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"
和A = 2
以及c17 = 3.14
之类的行写自己,然后你以后可以将它们粘贴在其他对象上(例如F = 10
或F = None
;它们都是一样的。)
Briggs假装您可能想写的所有可能的贴纸已经卡在None
对象上。
答案 1 :(得分:55)
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
也是一个值,虽然通常用于信号空白。你正在阅读的那本书在这一点上有误导性。
答案 2 :(得分:19)
这是Python documentation对None
所说的内容:
types.NoneType的唯一值。没有经常用来表示 没有值,因为默认参数没有传递给a 功能
在版本2.4中更改:对无分配是非法的并且提出了 的SyntaxError。
注意名称无和调试无法重新分配(分配给 它们,即使作为属性名称,也引发了SyntaxError),所以它们可以 被认为是“真正的”常数。
让我们确认None
第一个
print type(None)
print None.__class__
<强>输出强>
<type 'NoneType'>
<type 'NoneType'>
基本上,NoneType
是一种数据类型,就像int
,float
等。您可以在 {{3}中查看Python中可用的默认类型列表}
并且,None
是NoneType
类的实例。所以我们可能想要自己创建None
的实例。我们试试吧
print types.IntType()
print types.NoneType()
<强>输出强>
0
TypeError: cannot create 'NoneType' instances
很明显,无法创建NoneType
个实例。我们不必担心值None
的唯一性。
让我们检查一下我们如何在内部实施None
。
print dir(None)
<强>输出强>
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
__setattr__
除外,其他所有属性都是只读属性。因此,我们无法改变None
的属性。
让我们尝试将新属性添加到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
实例上动态创建属性。
让我们检查一下None
分配内容时会发生什么。根据文档,它应该抛出SyntaxError
。这意味着,如果我们将某些内容分配给None
,程序将根本不会被执行。
None = 1
<强>输出强>
SyntaxError: cannot assign to None
我们确定了
None
是NoneType
None
无法拥有新属性None
的现有属性无法更改。NoneType
None
的引用。因此,正如文档中所述,None
可以真正被视为true constant
。
快乐知道None
:)
答案 3 :(得分:9)
The book显然是在试图极大地简化None
的含义。 Python变量没有一个初始的空状态 - Python变量是bound (only) when they're defined。如果没有给它赋值,就无法创建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
作为正常输入。>>> 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
答案 4 :(得分:4)
其他答案已经很好地解释了 无 的含义。但是,我仍然想用一个例子来说明这一点。
示例:强>
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参数都将设置为默认值 [] 。
然而,实际发生的是新的默认列表仅在定义函数时创建一次,然后在没有指定list参数的情况下调用extendList时随后使用相同的列表。这是因为默认参数中的表达式是在定义函数时计算的,而不是在调用函数时。
list1 和 list3 因此在相同的默认列表上运行,而 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的示例信用
答案 5 :(得分:3)
None是单个对象(意味着只有一个None),在语言和库中的许多地方用于表示缺少其他值。
例如:
如果d
是字典,d.get(k)
将返回d[k]
(如果存在),但是{{ 1}}如果None
没有密钥d
。
从一篇出色的博客中了解此信息:http://python-history.blogspot.in/
答案 6 :(得分:3)
所有这些都是很好的答案,但是我认为还有更多的解释为什么None
是有用的。
想象一下,您在婚礼上收集了RSVP。您想记录每个人是否参加。如果他们正在参加,则设置person.attending = True
。如果他们不参加,请设置person.attending = False
。如果您尚未收到任何RSVP,请person.attending = None
。这样,您可以区分无信息None
和否定答案。
答案 7 :(得分:1)
我喜欢代码示例(以及水果),所以让我告诉你
apple = "apple"
print(apple)
>>> apple
apple = None
print(apple)
>>> None
无意义,没有任何价值。
无评估结果为假。
答案 8 :(得分:-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