Создание пустого объекта в Python

Существуют ли ярлыки для определения пустого объекта в Python или вам всегда нужно создавать экземпляр пользовательского пустого класса?

Изменить: я имею в виду пустой объект, используемый для печати утки.

10 ответов

Решение

Вы можете использовать тип, чтобы создать новый класс на лету, а затем создать его экземпляр. Вот так:

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

Аргументы для ввода: Имя класса, кортеж базовых классов и словарь объекта. Который может содержать функции (методы объекта) или атрибуты.

Вы можете сократить первую строку до

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

Потому что по умолчанию тип создает новые классы стилей, которые наследуются от объекта.

type используется в Python для метапрограммирования.

Но если вы просто хотите создать экземпляр объекта. Затем просто создайте его экземпляр. Как Лейлот предлагает.

Создание экземпляра такого нового класса имеет важное отличие, которое может быть полезным.

>>> 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'
>>> 

Да, в 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'

Один простой, менее пугающий на вид способ создания пустого (-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!'

Вы сказали это в вопросе, но, поскольку в ответе не упоминалось об этом с кодом, это, вероятно, одно из самых чистых решений:

class Myobject:
    pass

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

Что вы подразумеваете под "пустым объектом"? Экземпляр класса object? Вы можете просто запустить

a = object()

или, может быть, вы имеете в виду инициализацию для нулевой ссылки? Тогда вы можете использовать

a = None

Вы можете использовать

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')]

Все предложенные решения несколько неловки.

Я нашел способ, который не является хакерским, но на самом деле соответствует оригинальному дизайну.

>>> 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 "/opt/prezi/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 здесь.

Создает новый пустой объект Set. Если указан необязательный параметр iterable, обновляет набор элементами, полученными в результате итерации. Все элементы в итерации должны быть неизменяемыми или преобразовываться в неизменяемые с использованием протокола, описанного в разделе Протокол для автоматического преобразования в неизменяемые.

Пример:

myobj = set()
for i in range(1,10): myobj.add(i)
print(myobj)

In my opinion, the easiest way is:

def x():pass
x.test = 'Hello, world!'

Если есть желаемый тип пустого объекта, другими словами, вы хотите его создать, но не вызывайте __init__ инициализатор, вы можете использовать __new__:

      class String(object):
    ...

uninitialized_empty_string = String.__new__(String)

Источник: /questions/5156048/python-sozdanie-ekzemplyara-klassa-bez-vyizova-initsializatora/5156056#5156056.

Другие вопросы по тегам