Python中的空对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3289601/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
null object in Python?
提问by Lizard
How do I refer to the null object in Python?
如何在 Python 中引用 null 对象?
采纳答案by Ben James
In Python, the 'null' object is the singleton None.
在 Python 中,“空”对象是单例对象None。
The best way to check things for "Noneness" is to use the identity operator, is:
检查“Noneness”的最佳方法是使用身份运算符is:
if foo is None:
...
回答by AndiDog
回答by Paolo Rovelli
In Python, to represent the absence of a value, you can use the Nonevalue (types.NoneType.None) for objects and ""(or len() == 0) for strings. Therefore:
在 Python 中,为了表示没有值,您可以对对象使用None值(types.NoneType.None),对字符串使用""(或len() == 0)。所以:
if yourObject is None: # if yourObject == None:
...
if yourString == "": # if yourString.len() == 0:
...
Regarding the difference between "==" and "is", testing for object identity using "==" should be sufficient. However, since the operation "is" is defined as the object identity operation, it is probably more correct to use it, rather than "==". Not sure if there is even a speed difference.
关于“==”和“is”之间的区别,使用“==”测试对象身份应该就足够了。但是,由于操作“is”被定义为对象标识操作,因此使用它可能更正确,而不是“==”。不确定是否有速度差异。
Anyway, you can have a look at:
不管怎样,你可以看看:
- Python Built-in Constantsdoc page.
- Python Truth Value Testingdoc page.
回答by artejera
Per Truth value testing, 'None' directly tests as FALSE, so the simplest expression will suffice:
根据真值测试,“无”直接测试为 FALSE,因此最简单的表达式就足够了:
if not foo:
回答by Michael Ekoka
None, Python's null?
None,Python的null?
There's no nullin Python, instead there's None. As stated already the most accurate way to test that something has been given Noneas a value is to use the isidentity operator, which tests that two variables refer to the same object.
nullPython 中没有,而是有None. 如前所述,测试某些东西是否已None作为值给出的最准确方法是使用is恒等运算符,它测试两个变量是否指向同一个对象。
>>> foo is None
True
>>> foo = 'bar'
>>> foo is None
False
The basics
基础知识
There is and can only be one None
有且只能有一个 None
Noneis the sole instance of the class NoneTypeand any further attempts at instantiating that class will return the same object, which makes Nonea singleton. Newcomers to Python often see error messages that mention NoneTypeand wonder what it is. It's my personal opinion that these messages could simply just mention Noneby name because, as we'll see shortly, Noneleaves little room to ambiguity. So if you see some TypeErrormessage that mentions that NoneTypecan't do this or can't do that, just know that it's simply the one Nonethat was being used in a way that it can't.
None是该类的唯一实例,NoneType任何进一步实例化该类的尝试都将返回相同的对象,这将None成为单例。Python 的新手经常看到错误消息,提到NoneType并想知道它是什么。我个人认为,这些消息可以简单地None按名称提及,因为我们很快就会看到,None几乎没有歧义的余地。因此,如果您看到某些TypeError消息提到NoneType不能执行此操作或不能执行此操作,请知道它只None是以不能执行的方式使用的消息。
Also, Noneis a built-in constant, as soon as you start Python it's available to use from everywhere, whether in module, class, or function. NoneTypeby contrast is not, you'd need to get a reference to it first by querying Nonefor its class.
此外,它None是一个内置常量,一旦您启动 Python,它就可以在任何地方使用,无论是在模块、类还是函数中。NoneType相比之下,您需要首先通过查询None它的类来获得对它的引用。
>>> NoneType
NameError: name 'NoneType' is not defined
>>> type(None)
NoneType
You can check None's uniqueness with Python's identity function id(). It returns the unique number assigned to an object, each object has one. If the id of two variables is the same, then they point in fact to the same object.
您可以None使用 Python 的 identity 函数检查的唯一性id()。它返回分配给一个对象的唯一编号,每个对象都有一个。如果两个变量的id相同,那么它们实际上指向的是同一个对象。
>>> NoneType = type(None)
>>> id(None)
10748000
>>> my_none = NoneType()
>>> id(my_none)
10748000
>>> another_none = NoneType()
>>> id(another_none)
10748000
>>> def function_that_does_nothing(): pass
>>> return_value = function_that_does_nothing()
>>> id(return_value)
10748000
Nonecannot be overwritten
None不能被覆盖
In much older version of Python (before 2.4) it was possible to reassign None, but not anymore. Not even as a class attribute or in the confines of a function.
在更旧的 Python 版本(2.4 之前)中,可以重新分配None,但现在不能了。甚至不是作为类属性或在函数范围内。
# In Python 2.7
>>> class SomeClass(object):
... def my_fnc(self):
... self.None = 'foo'
SyntaxError: cannot assign to None
>>> def my_fnc():
None = 'foo'
SyntaxError: cannot assign to None
# In Python 3.5
>>> class SomeClass:
... def my_fnc(self):
... self.None = 'foo'
SyntaxError: invalid syntax
>>> def my_fnc():
None = 'foo'
SyntaxError: cannot assign to keyword
It's therefore safe to assume that all Nonereferences are the same. There's no "custom" None.
因此可以安全地假设所有None引用都是相同的。没有“自定义” None。
To test for Noneuse the isoperator
测试None使用is操作符
When writing code you might be tempted to test for Nonenesslike this:
在编写代码时,您可能会像这样测试Noneness:
if value==None:
pass
Or to test for falsehood like this
或者像这样测试虚假
if not value:
pass
You need to understand the implications and why it's often a good idea to be explicit.
您需要了解其中的含义以及为什么明确表示通常是个好主意。
Case 1: testing if a value is None
案例 1:测试一个值是否为 None
why do this
为什么要这样做
value is None
rather than
而不是
value==None
The first is equivalent to:
第一个相当于:
id(value)==id(None)
Whereas the expression value==Noneis in fact applied like this
而表达式value==None实际上是这样应用的
value.__eq__(None)
if the value really is Nonethen you'll get what you expected.
如果价值真的是None那么你会得到你所期望的。
>>> nothing = function_that_does_nothing()
>>> nothing.__eq__(None)
True
In most common cases the outcome will be the same, but the __eq__()method opens a door that voids any guarantee of accuracy, since it can be overridden in a class to provide special behavior.
在大多数常见情况下,结果将是相同的,但该__eq__()方法打开了一扇门,使任何准确性保证无效,因为它可以在类中被覆盖以提供特殊行为。
Consider this class.
考虑这个类。
>>> class Empty(object):
... def __eq__(self, other):
... return not other
So you try it on Noneand it works
所以你想它None和它的工作原理
>>> empty = Empty()
>>> empty==None
True
But then it also works on the empty string
但它也适用于空字符串
>>> empty==''
True
And yet
但是
>>> ''==None
False
>>> empty is None
False
Case 2: Using Noneas a boolean
案例 2:None用作布尔值
The following two tests
下面两个测试
if value:
# do something
if not value:
# do something
are in fact evaluated as
实际上被评估为
if bool(value):
# do something
if not bool(value):
# do something
Noneis a "falsey", meaning that if cast to a boolean it will return Falseand if applied the notoperator it will return True. Note however that it's not a property unique to None. In addition to Falseitself, the property is shared by empty lists, tuples, sets, dicts, strings, as well as 0, and all objects from classes that implement the __bool__()magic method to return False.
None是一个“falsey”,这意味着如果转换为布尔值,它将返回False,如果应用not运算符,它将返回True。但请注意,它不是None. 除了False自身之外,该属性还被空列表、元组、集合、字典、字符串以及 0 以及所有实现了__bool__()返回的魔术方法的类的对象共享False。
>>> bool(None)
False
>>> not None
True
>>> bool([])
False
>>> not []
True
>>> class MyFalsey(object):
... def __bool__(self):
... return False
>>> f = MyFalsey()
>>> bool(f)
False
>>> not f
True
So when testing for variables in the following way, be extra aware of what you're including or excluding from the test:
因此,在以下列方式测试变量时,请特别注意您在测试中包含或排除的内容:
def some_function(value=None):
if not value:
value = init_value()
In the above, did you mean to call init_value()when the value is set specifically to None, or did you mean that a value set to 0, or the empty string, or an empty list should also trigger the initialization. Like I said, be mindful. As it's often the case in Python explicit is better than implicit.
在上面,您的意思是init_value()在将值专门设置为 时调用None,还是说设置为 的值0、空字符串或空列表也应触发初始化。就像我说的,要注意。因为 Python 中的情况通常是显式优于隐式。
Nonein practice
None在实践中
Noneused as a signal value
None用作信号值
Nonehas a special status in Python. It's a favorite baseline value because many algorithms treat it as an exceptional value. In such scenarios it can be used as a flag to signal that a condition requires some special handling (such as the setting of a default value).
None在 Python 中具有特殊地位。这是最喜欢的基线值,因为许多算法将其视为特殊值。在这种情况下,它可以用作标志来表示条件需要一些特殊处理(例如设置默认值)。
You can assign Noneto the keyword arguments of a function and then explicitly test for it.
您可以分配None给函数的关键字参数,然后对其进行显式测试。
def my_function(value, param=None):
if param is None:
# do something outrageous!
You can return it as the default when trying to get to an object's attribute and then explicitly test for it before doing something special.
您可以在尝试获取对象的属性时将其返回为默认值,然后在执行特殊操作之前对其进行显式测试。
value = getattr(some_obj, 'some_attribute', None)
if value is None:
# do something spectacular!
By default a dictionary's get()method returns Nonewhen trying to access a non-existing key:
默认情况下,字典的get()方法None在尝试访问不存在的键时返回:
>>> some_dict = {}
>>> value = some_dict.get('foo')
>>> value is None
True
If you were to try to access it by using the subscript notation a KeyErrorwould be raised
如果您尝试使用下标符号来访问它,KeyError则会引发
>>> value = some_dict['foo']
KeyError: 'foo'
Likewise if you attempt to pop a non-existing item
同样,如果您尝试弹出一个不存在的项目
>>> value = some_dict.pop('foo')
KeyError: 'foo'
which you can suppress with a default value that is usually set to None
您可以使用通常设置为的默认值来抑制它 None
value = some_dict.pop('foo', None)
if value is None:
# booom!
Noneused as both a flag and valid value
None用作标志和有效值
The above described uses of Noneapply when it is not considered a valid value, but more like a signal to do something special. There are situations however where it sometimes matters to know where Nonecame from because even though it's used as a signal it could also be part of the data.
None当它不被视为有效值时,上述应用的使用更像是做一些特殊事情的信号。然而,在某些情况下,有时了解None来自何处很重要,因为即使它被用作信号,它也可能是数据的一部分。
When you query an object for its attribute with getattr(some_obj, 'attribute_name', None)getting back Nonedoesn't tell you if the attribute you were trying to access was set to Noneor if it was altogether absent from the object. Same situation when accessing a key from a dictionary like some_dict.get('some_key'), you don't know if some_dict['some_key']is missing or if it's just set to None. If you need that information, the usual way to handle this is to directly attempt accessing the attribute or key from within a try/exceptconstruct:
当您查询的对象与属性getattr(some_obj, 'attribute_name', None)又回到None不告诉你,如果你要访问的属性设置为None,或者如果它是从对象完全不存在的。从字典中访问键时的情况相同,例如some_dict.get('some_key'),您不知道some_dict['some_key']是丢失还是设置为None。如果您需要该信息,处理此问题的常用方法是直接尝试从try/except构造中访问属性或键:
try:
# equivalent to getattr() without specifying a default
# value = getattr(some_obj, 'some_attribute')
value = some_obj.some_attribute
# now you handle `None` the data here
if value is None:
# do something here because the attribute was set to None
except AttributeError:
# we're now hanling the exceptional situation from here.
# We could assign None as a default value if required.
value = None
# In addition, since we now know that some_obj doesn't have the
# attribute 'some_attribute' we could do something about that.
log_something(some_obj)
Similarly with dict:
与 dict 类似:
try:
value = some_dict['some_key']
if value is None:
# do something here because 'some_key' is set to None
except KeyError:
# set a default
value = None
# and do something because 'some_key' was missing
# from the dict.
log_something(some_dict)
The above two examples show how to handle object and dictionary cases, what about functions? Same thing, but we use the double asterisks keyword argument to that end:
上面两个例子展示了如何处理对象和字典的情况,函数呢?同样的事情,但我们为此使用双星号关键字参数:
def my_function(**kwargs):
try:
value = kwargs['some_key']
if value is None:
# do something because 'some_key' is explicitly
# set to None
except KeyError:
# we assign the default
value = None
# and since it's not coming from the caller.
log_something('did not receive "some_key"')
Noneused only as a valid value
None仅用作有效值
If you find that your code is littered with the above try/exceptpattern simply to differentiate between Noneflags and Nonedata, then just use another test value. There's a pattern where a value that falls outside the set of valid values is inserted as part of the data in a data structure and is used to control and test special conditions (e.g. boundaries, state, etc). Such a value is called a sentineland it can be used the way Noneis used as a signal. It's trivial to create a sentinel in Python.
如果您发现您的代码充斥着上述try/except模式只是为了区分None标志和None数据,那么只需使用另一个测试值。有一种模式,其中将超出有效值集的值作为数据的一部分插入到数据结构中,并用于控制和测试特殊条件(例如边界、状态等)。这样的值称为哨兵,它可以用作None信号的方式。在 Python 中创建哨兵很简单。
undefined = object()
The undefinedobject above is unique and doesn't do much of anything that might be of interest to a program, it's thus an excellent replacement for Noneas a flag. Some caveats apply, more about that after the code.
undefined上面的对象是独一无二的,并没有做任何程序可能感兴趣的事情,因此它是None作为标志的绝佳替代品。一些警告适用,更多关于代码之后的内容。
With function
带功能
def my_function(value, param1=undefined, param2=undefined):
if param1 is undefined:
# we know nothing was passed to it, not even None
log_something('param1 was missing')
param1 = None
if param2 is undefined:
# we got nothing here either
log_something('param2 was missing')
param2 = None
With dict
用字典
value = some_dict.get('some_key', undefined)
if value is None:
log_something("'some_key' was set to None")
if value is undefined:
# we know that the dict didn't have 'some_key'
log_something("'some_key' was not set at all")
value = None
With an object
有对象
value = getattr(obj, 'some_attribute', undefined)
if value is None:
log_something("'obj.some_attribute' was set to None")
if value is undefined:
# we know that there's no obj.some_attribute
log_something("no 'some_attribute' set on obj")
value = None
As I mentioned earlier custom sentinels come with some caveats. First, they're not keywords like None, so python doesn't protect them. You can overwrite your undefinedabove at any time, anywhere in the module it's defined, so be careful how you expose and use them. Next, the instance returned by object()is not a singleton, if you make that call 10 times you get 10 different objects. Finally, usage of a sentinel is highly idiosyncratic. A sentinel is specific to the library it's used in and as such its scope should generally be limited to the library's internals. It shouldn't "leak" out. External code should only become aware of it, if their purpose is to extend or supplement the library's API.
正如我之前提到的,自定义哨兵带有一些警告。首先,它们不是像 那样的关键字None,所以 python 不保护它们。您可以随时覆盖undefined上面定义的模块中的任何位置,因此请注意公开和使用它们的方式。接下来,返回的实例object()不是单例,如果你调用 10 次,你会得到 10 个不同的对象。最后,哨兵的使用是非常特殊的。哨兵特定于它所使用的库,因此其范围通常应限于库的内部。它不应该“泄漏”出来。外部代码只有在其目的是扩展或补充库的 API 时才应该意识到它。
回答by Michael Ekoka
Null is a special object type like:
Null 是一种特殊的对象类型,例如:
>>>type(None)
<class 'NoneType'>
You can check if an object is in class 'NoneType':
您可以检查对象是否在类“NoneType”中:
>>>variable = None
>>>variable is None
True
More information is available at Python Docs
Python 文档中提供了更多信息

