I'm familiar with Java's null and C++'s nullptr, plus similar concepts from several scripting languages. None looks remarkably like Python's version of that same old theme.
And then I ran across this function declaration:
numpy.amin(a, axis=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)
What's the difference between None and <no value>? I'm guessing this is just a documentation generation thing when there's no defined default, but then why not just not list a default at all?
It's just a documentation thing, there is no such concept in Python itself.
Take into account that None in itself is also a valid object. Sometimes you want to accept None as a valid value for an argument, so you can't use that as the default value for an optional parameter. You wouldn't be able to distinguish between the default None and someone passing in None explicitly, since it's a singleton!
If I needed to define such a function, I'd use a different singleton sentinel. You can create one from just about anything, but simplest is to use an object() instance:
_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
And perhaps I'd also use <no value> in the documentation to indicate that baz is optional. It all depends on the local conventions. The Python documentation itself uses [...] around optional arguments, for example.
numpy.amin() is actually a proxy function; it delegates the actual work either to numpy.minimum() (via ufunc.reduce(), or, if the first argument is a subclass that implements an amin() method, to that method of the subclass. Because the latter should be able to set their own defaults, using a sentinel lets the numpy.amin() implementation pass on only those keyword arguments that actually were given an explicit value, without dictating what kind of sentinel the subclass .amin() implementations should use or what types they accept.
The Numpy project actually created their own singleton class to act as a sentinel so they could give the object a helpful repr() output:
>>> from numpy._globals import _NoValue
>>> _NoValue
<no value>
>>> type(_NoValue)
<class 'numpy._globals._NoValueType'>
Finally, None should not be compared with null or nullptr. None is a singleton object, something to reference instead of another object. null and nullptr are used to signal the absence of a reference, and can be passed around like other scalar values. You can't do this in Python, where everything is a valid reference to an object. (At most, you get a NameError or UnboundLocal exception if you tried to use a name that hasn't been bound to yet in its namespace).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With