什么是无价值?

时间:2013-10-20 02:10:23

标签: python variables if-statement

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

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

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

  

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

这是什么意思?

答案很棒,但由于我对计算机世界的了解不足(我还没有学过课程,对象等),所以我不理解大部分答案。这句话是什么意思?

  

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

决赛:

最后,我从不同的答案中得到了答案。我必须感谢那些把时间用来帮助我的人(特别是Martijn Pieters和DSM),我希望我能选择所有答案作为最佳答案,但选择仅限于一个。所有答案都很棒。

9 个答案:

答案 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 = NoneF重置为其原始状态,那么它现在应该在那里,我们应该看到

>>> print(F)
None

就像我们输入F = None并将贴纸贴在None上一样。


这就是所有这一切。实际上,Python附带了一些贴在对象上的贴纸(内置名称),但是其他的你必须使用F = "fork"A = 2以及c17 = 3.14之类的行写自己,然后你以后可以将它们粘贴在其他对象上(例如F = 10F = 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 documentationNone所说的内容:

  

types.NoneType的唯一值。没有经常用来表示   没有值,因为默认参数没有传递给a   功能

     

在版本2.4中更改:对无分配是非法的并且提出了   的SyntaxError。

     

注意名称无和调试无法重新分配(分配给   它们,即使作为属性名称,也引发了SyntaxError),所以它们可以   被认为是“真正的”常数。

  1. 让我们确认None第一个

    的类型
    print type(None)
    print None.__class__
    

    <强>输出

    <type 'NoneType'>
    <type 'NoneType'>
    
  2. 基本上,NoneType是一种数据类型,就像intfloat等。您可以在 {{3}中查看Python中可用的默认类型列表}

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

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

      <强>输出

      0
      TypeError: cannot create 'NoneType' instances
      
    2. 很明显,无法创建NoneType个实例。我们不必担心值None的唯一性。

      1. 让我们检查一下我们如何在内部实施None

        print dir(None)
        

        <强>输出

        ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', 
         '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
         '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
        
      2. __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'
          
        2. 上述语句分别产生这些错误消息。这意味着,我们无法在None实例上动态创建属性。

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

            None = 1
            

            <强>输出

            SyntaxError: cannot assign to None
            
          2. 我们确定了

            1. NoneNoneType
            2. 的一个实例
            3. None无法拥有新属性
            4. None的现有属性无法更改。
            5. 我们无法创建NoneType
            6. 的其他实例
            7. 我们甚至无法通过为其指定值来更改对None的引用。
            8. 因此,正如文档中所述,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这样的特殊值,其含义不清楚,
  2. 我们的功能实际上可能需要处理-1作为正常输入。
  3. >>> 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