103

在 Python 中定义空对象是否有任何快捷方式,或者您是否总是必须创建自定义空类的实例?

编辑:我的意思是一个可用于鸭子打字的空对象。

4

10 回答 10

120

您可以使用 type 动态创建一个新类,然后实例化它。像这样:

>>> t = type('test', (object,), {})()
>>> t
<__main__.test at 0xb615930c>

type 的参数是:类名、基类元组和对象的字典。其中可以包含函数(对象的方法)或属性。

您实际上可以将第一行缩短为

>>> t = type('test', (), {})()
>>> t.__class__.__bases__
(object,)

因为默认情况下 type 创建从 object 继承的新样式类。

type在 Python 中用于元编程

但是如果你只是想创建一个对象的实例。然后,只需创建它的一个实例。就像 lejlot 建议的那样。

像这样创建一个新类的实例有一个可能有用的重要区别。

>>> a = object()
>>> a.whoops = 1
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'whoops'

然而:

>>> b = type('', (), {})()
>>> b.this_works = 'cool'
>>> 
于 2013-10-20T11:30:41.473 回答
111

是的,在 Python 3.3中添加了SimpleNamespace

与对象不同,使用 SimpleNamespace,您可以添加和删除属性。如果使用关键字参数初始化 SimpleNamespace 对象,则会将它们直接添加到底层命名空间。

例子:

import types

x = types.SimpleNamespace()
x.happy = True

print(x.happy) # True

del x.happy
print(x.happy) # AttributeError. object has no attribute 'happy'
于 2017-01-20T13:54:18.930 回答
60

创建空(-ish)对象的一种简单、看起来不那么可怕的方法是利用函数是 Python 中的对象这一事实,包括 Lambda 函数:

obj = lambda: None
obj.test = "Hello, world!"

例如:

In [18]: x = lambda: None

In [19]: x.test = "Hello, world!"

In [20]: x.test
Out[20]: 'Hello, world!'
于 2016-05-31T08:27:20.037 回答
13

您在问题中说过,但由于没有用代码提到它,这可能是最干净的解决方案之一:

class Myobject:
    pass

x = Myobject()
x.test = "Hello, world!"  # working

于 2020-04-13T15:58:37.670 回答
11

“空对象”是什么意思?类的实例object?你可以简单地运行

a = object()

或者你的意思是初始化空引用?然后你可以使用

a = None
于 2013-10-20T11:29:50.947 回答
4

您可以使用

x = lambda: [p for p in x.__dict__.keys()]

然后

x.p1 = 2
x.p2 = "Another property"

x()
# gives
# ['p1', 'p2']

[(p, getattr(x,p)) for p in x()]
# gives
# [('p1', 2), ('p2', 'Another property')]
于 2020-09-23T10:35:58.563 回答
3

所有提出的解决方案都有些尴尬。

我找到了一种方法,它不是hacky,但实际上是根据原始设计。

>>> from mock import Mock
>>> foo = Mock(spec=['foo'], foo='foo')
>>> foo.foo
'foo'
>>> foo.bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/.../virtualenv/local/lib/python2.7/site-packages/mock/mock.py", line 698, in __getattr__
    raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'bar'

在此处查看 unittest.mock 的文档。

于 2018-09-10T13:18:25.827 回答
2

在我看来,最简单的方法是:

def x():pass
x.test = 'Hello, world!'
于 2020-08-17T21:13:09.020 回答
2

构造一个新的空 Set 对象。如果提供了可选的可迭代参数,则使用从迭代中获得的元素更新集合。iterable 中的所有元素都应该是不可变的,或者可以使用自动转换为不可变的协议一节中描述的协议转换为不可变的。

前任:

myobj = set()
for i in range(1,10): myobj.add(i)
print(myobj)
于 2019-01-12T17:43:45.427 回答
0

如果有所需的空对象类型,换句话说,您想创建它但不调用__init__初始化程序,您可以使用__new__

class String(object):
    ...

uninitialized_empty_string = String.__new__(String)

资料来源:https ://stackoverflow.com/a/2169191/6639500 。

于 2021-10-08T18:55:39.543 回答