The*_*ver 116 python variables if-statement
我一直在研究Python,我读了一章描述了它的None价值,但遗憾的是这本书在某些方面并不是很清楚.如果我在那里分享,我想我会找到问题的答案.
我想知道它的None价值是什么,你用它做什么?
而且,我没有得到这本书的这一部分:
分配的值
None给变量是将其重置到其原始的,空的状态的一种方法.
那是什么意思?
答案很棒,但由于我对计算机世界的了解不足(我还没有学过课程,对象等),所以我不理解大多数答案.这句话是什么意思?
分配的值
None给变量是将其重置到其原始的,空的状态的一种方法.
最后:
最后,我通过寻找不同的答案得到了答案.我必须感谢那些把时间用来帮助我的人(特别是Martijn Pieters和DSM),我希望我能选择所有答案作为最佳答案,但选择仅限于一个.所有答案都很棒.
DSM*_*DSM 88
Martijn的回答解释了NonePython中的内容,并正确地指出该书具有误导性.因为Python程序员通常不会说
分配的值
None给变量是将其重置到其原始的,空的状态的一种方法.
很难用一种有意义的方式来解释布里格斯的意思,并解释为什么这里没有人对它感到满意.一个类比可能会有所帮助:
在Python中,变量名称就像放在对象上的贴纸.每个贴纸都有一个独特的名字写在上面,它一次只能放在一个物体上,但如果你愿意的话,可以在同一个物体上放一个以上的贴纸.当你写作
F = "fork"
Run Code Online (Sandbox Code Playgroud)
你把标签"F"放在一个字符串对象上"fork".如果你再写
F = None
Run Code Online (Sandbox Code Playgroud)
你将贴纸移动到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
Run Code Online (Sandbox Code Playgroud)
这NameError意味着Python无法识别名称F,因为没有这样的贴纸.如果布里格斯是正确的并且F = None重置F到原来的状态,那么现在应该在那里,我们应该看到
>>> print(F)
None
Run Code Online (Sandbox Code Playgroud)
就像我们打字后F = None贴上标签一样None.
这就是所有这一切.实际上,Python附带了一些贴在对象上的贴纸(内置名称),但是其他的你必须使用F = "fork"和A = 2和之类的行写自己c17 = 3.14,然后你可以将它们粘贴在其他对象上(比如F = 10或者F = None;它们都是一样的) .)
布里格斯假装你可能想写的所有可能的贴纸已经粘在了这个None对象上.
Mar*_*ers 60
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
Run Code Online (Sandbox Code Playgroud)
另一个用途是为"空"默认值提供可选参数:
def spam(foo=None):
if foo is not None:
# foo was specified, do something clever!
Run Code Online (Sandbox Code Playgroud)
该函数spam()有一个可选参数; 如果您在spam()未指定的情况下调用它,则会为其指定默认值None,从而可以轻松检测函数是否使用参数调用.
其他语言也有类似的概念.SQL有NULL; JavaScript有undefined 和 null等.
请注意,在Python中,变量因使用而存在.您不需要首先声明变量,因此Python 中没有真正的空变量.将变量设置None为与将其设置为默认空值不同; None也是一个值,虽然通常用于表示空虚.你正在阅读的这本书在这一点上具有误导性.
the*_*eye 19
这就是Python文档所要说的None:
types.NoneType的唯一值.None通常用于表示缺少值,因为默认参数未传递给函数.
版本2.4中更改:分配给None是非法的并引发SyntaxError.
注意名称无和调试无法重新分配(对它们的赋值,即使作为属性名称,引发SyntaxError),因此它们可以被视为"真"常量.
让我们确认的类型None第一
print type(None)
print None.__class__
Run Code Online (Sandbox Code Playgroud)
产量
<type 'NoneType'>
<type 'NoneType'>
Run Code Online (Sandbox Code Playgroud)基本上,NoneType是一种数据类型一样int,float等您可以检查出的默认类型在Python提供的列表8.15.types - 内置类型的名称.
并且,None是一个NoneType类的实例.所以我们可能想要创建None自己的实例.我们试试吧
print types.IntType()
print types.NoneType()
Run Code Online (Sandbox Code Playgroud)
产量
0
TypeError: cannot create 'NoneType' instances
Run Code Online (Sandbox Code Playgroud)很清楚,无法创建NoneType实例.我们不必担心价值的独特性None.
我们来看看我们在None内部实施的方式.
print dir(None)
Run Code Online (Sandbox Code Playgroud)
产量
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
Run Code Online (Sandbox Code Playgroud)除此之外__setattr__,所有其他都是只读属性.所以,我们无法改变其属性None.
让我们尝试添加新属性 None
setattr(types.NoneType, 'somefield', 'somevalue')
setattr(None, 'somefield', 'somevalue')
None.somefield = 'somevalue'
Run Code Online (Sandbox Code Playgroud)
产量
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'
Run Code Online (Sandbox Code Playgroud)上述语句分别产生这些错误消息.这意味着,我们无法在None实例上动态创建属性.
让我们检查一下我们分配什么时会发生什么None.根据文档,它应该抛出一个SyntaxError.这意味着,如果我们分配一些东西None,程序将根本不会被执行.
None = 1
Run Code Online (Sandbox Code Playgroud)
产量
SyntaxError: cannot assign to None
Run Code Online (Sandbox Code Playgroud)我们确立了这一点
None 是一个实例 NoneTypeNone 不能有新的属性None无法更改.NoneTypeNone通过为其赋值来更改引用.因此,正如文档中提到的,None可以真正被视为一个true constant.
快乐知道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
Run Code Online (Sandbox Code Playgroud)
但有时你想根据变量是否定义来使函数表示不同的东西.您可以使用默认值创建参数None:
>>> def test(x=None):
... if x is None:
... print('no x here')
... else:
... print(x)
...
>>> test()
no x here
>>> test('x!')
x!
Run Code Online (Sandbox Code Playgroud)
None在这种情况下,该值是特殊值的事实并不十分重要.我可以使用任何默认值:
>>> def test(x=-1):
... if x == -1:
... print('no x here')
... else:
... print(x)
...
>>> test()
no x here
>>> test('x!')
x!
Run Code Online (Sandbox Code Playgroud)
......但是None周围有两个好处:
-1如其含义不清楚,并且-1 as a normal input.>>> test(-1)
no x here
Run Code Online (Sandbox Code Playgroud)
oops!
So the book is a little misleading mostly in its use of the word reset – assigning None to a name is a signal to a programmer that that value isn't being used or that the function should behave in some default way, but to reset a value to its original, undefined state you must use the del keyword:
>>> x = 3
>>> x
3
>>> del x
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
Run Code Online (Sandbox Code Playgroud)
None 是一个单例对象(意味着只有一个 None),在语言和库中的许多地方使用来表示某些值的缺失。
例如:
ifd是字典,如果存在则d.get(k)返回,但if没有 key 。d[k]Nonedk
从一个很棒的博客中阅读此信息:https://python-history.blogspot.com/2013/11/story-of-none-true-false.html
其他答案已经很好地解释了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
Run Code Online (Sandbox Code Playgroud)
现在尝试猜测上面列表的输出。好吧,答案令人惊讶地如下:
list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']
Run Code Online (Sandbox Code Playgroud)
但为什么?
许多人会错误地期望list1等于[10],list3等于['a'],以为每次调用extendList时,list参数将被设置为其默认值[]。
但是,实际发生的情况是,在定义函数时,仅会创建一次新的默认列表,然后,在调用extendList且未指定list参数的情况下,随后将使用同一列表。这是因为默认参数中的表达式是在定义函数时计算的,而不是在调用函数时计算的。
因此,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
Run Code Online (Sandbox Code Playgroud)
使用此修订的实现,输出将是:
list1 = [10]
list2 = [123]
list3 = ['a']
Run Code Online (Sandbox Code Playgroud)
注意 -贷记至toptal.com的示例