我熟悉Java的null
和C++的nullptr
,还有几种脚本语言中类似的概念。None
看起来非常像Python中的那个旧主题。
然后我遇到了这个函数声明:
numpy.amin(a, axis=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)
None
和<no value>
有什么区别?我猜想这只是在没有定义默认值时生成文档的一个方式,但为什么不完全不列出默认值呢?
这只是一份文件记录,Python本身并没有这样的概念。
请注意,None
本身也是一个有效的对象。有时你想要将None
作为参数的有效值,因此不能将其用作可选参数的默认值。你无法区分默认值None
和显式传递的None
,因为它是一个单例!
如果我需要定义这样的函数,我会使用其他单例哨兵。你可以从任何东西创建一个,但最简单的方法是使用一个object()
实例:
_sentinel = object()
def foo(bar, baz=_sentinel):
if baz is not _sentinel:
# baz has a defined value, because it is
# not a reference to the sentinel
也许我在文档中还会使用<no value>
来表示baz
是可选的。这完全取决于当地的惯例。例如,Python文档本身在可选参数周围使用[...]
。
numpy.amin()
实际上是一个代理函数;它将实际工作委托给numpy.minimum()
(通过ufunc.reduce()
),或者如果第一个参数是实现了amin()
方法的子类,则委托给子类的该方法。由于后者应该能够设置自己的默认值,使用标志让numpy.amin()
实现只传递那些实际给定了显式值的关键字参数,而不指定子类.amin()
实现应该使用什么样的标志或接受什么类型。
Numpy项目实际上创建了自己的单例类作为标志,以便为对象提供有用的repr()
输出:
>>> from numpy._globals import _NoValue
>>> _NoValue
<no value>
>>> type(_NoValue)
<class 'numpy._globals._NoValueType'>
None
不应该与 null
或 nullptr
进行比较。 None
是一个单例对象,是一种可用于引用而非其他对象的东西。而 null
和 nullptr
用于表示没有引用,可以像其他标量值一样传递。在 Python 中,你无法这样做,因为所有东西都是一个有效的对象引用。最多,如果您尝试在其命名空间中使用尚未绑定到名称的名称,则会获得 NameError
或 UnboundLocal
异常。del
删除了它们的值。但是,您不能像使用null
或nullptr
那样在Python中传递和操作空引用。 - user2357112numpy.amin()
函数中,只有在未使用默认值时,keepdims
参数的值才会传递给 a.amin()
函数。因为 a
可以是 numpy.ndarray
的任何子类,所以如果 None
有任何特定含义,这取决于您传递的确切数组类型。开发人员不想限制可以使用哪些值,也不想防止这些类型选择不同的默认值。 - Martijn Pietersnp._NoValue
类的代码:
class _NoValueType(object):
"""Special keyword value.
The instance of this class may be used as the default value assigned to a
deprecated keyword in order to check if it has been given a user defined
value.
"""
__instance = None
def __new__(cls):
# ensure that only one instance exists
if not cls.__instance:
cls.__instance = super(_NoValueType, cls).__new__(cls)
return cls.__instance
# needed for python 2 to preserve identity through a pickle
def __reduce__(self):
return (self.__class__, ())
def __repr__(self):
return "<no value>"
File: /usr/local/lib/python3.6/dist-packages/numpy/_globals.py
Type: type
_NoValue
对象(很可能是通过_NoValue = object()
实现的)。他们需要这样做是因为任何值都是合理的,包括None
,因此需要一个单独的对象来指示用户未提供值(因为在函数中无法区分)。因此,确实,<no value>
是文档目的的特殊表示。 - a_guestNone
非常相似,并具有有用的repr()
。链接 - Martijn Pieters