什么是无价值?

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对象上.

  • 对于非程序员来说,这是一个很好的解释.非常感谢你! (3认同)
  • 抱歉,你说的 Briggs 是什么意思?你指的是这本书的作者吗?因为他的名字是 Jason R. Briggs。 (2认同)

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也是一个值,虽然通常用于表示空虚.你正在阅读的这本书在这一点上具有误导性.

  • @MartijnPieters:SQL*是一种编程语言,只是一个非常具体的目的,是声明性的. (5认同)
  • @daniel:作为一种编程语言,SQL有资格作为一个长期争论...请参阅http://stackoverflow.com/questions/900055/is-sql-or-even-tsql-turing-complete以获得有趣的角度. (3认同)

the*_*eye 19

这就是Python文档所要说的None:

types.NoneType的唯一值.None通常用于表示缺少值,因为默认参数未传递给函数.

版本2.4中更改:分配给None是非法的并引发SyntaxError.

注意名称无和调试无法重新分配(对它们的赋值,即使作为属性名称,引发SyntaxError),因此它们可以被视为"真"常量.

  1. 让我们确认的类型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 - 内置类型的名称.

  1. 并且,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.

  1. 我们来看看我们在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.

  1. 让我们尝试添加新属性 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实例上动态创建属性.

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

    None = 1
    
    Run Code Online (Sandbox Code Playgroud)

    产量

    SyntaxError: cannot assign to None
    
    Run Code Online (Sandbox Code Playgroud)

我们确立了这一点

  1. None 是一个实例 NoneType
  2. None 不能有新的属性
  3. 现有属性None无法更改.
  4. 我们无法创建其他实例 NoneType
  5. 我们甚至无法None通过为其赋值来更改引用.

因此,正如文档中提到的,None可以真正被视为一个true constant.

快乐知道None:)


koj*_*iro 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
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如其含义不清楚,并且
  2. Our function may actually need to handle -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)


Grv*_*agi 6

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


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

从一个很棒的博客中阅读此信息:https://python-history.blogspot.com/2013/11/story-of-none-true-false.html


Jad*_*eda 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
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参数的情况下,随后将使用同一列表。这是因为默认参数中的表达式是在定义函数时计算的,而不是在调用函数时计算的

因此,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
Run Code Online (Sandbox Code Playgroud)

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

list1 = [10]
list2 = [123]
list3 = ['a']
Run Code Online (Sandbox Code Playgroud)

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