Чи існують ярлики для визначення порожнього об'єкта в Python, чи завжди потрібно створювати екземпляр власного порожнього класу?
Редагувати: Я маю на увазі порожній об’єкт, придатний для набору качок.
Відповіді:
Ви можете використовувати type, щоб створити новий клас на льоту, а потім створити його екземпляр. Подобається так:
>>> t = type('test', (object,), {})()
>>> t
<__main__.test at 0xb615930c>
Аргументами для введення є: ім'я класу, сукупність базових класів та словник об'єкта. Які можуть містити функції (методи об’єкта) або атрибути.
Ви можете фактично скоротити перший рядок до
>>> t = type('test', (), {})()
>>> t.__class__.__bases__
(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'
>>>
Так, у 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 Functions:
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!'
x.__class__.somefunc
Що ви маєте на увазі під "порожнім об'єктом"? Екземпляр класу object
? Ви можете просто бігати
a = object()
чи, можливо, ви маєте на увазі ініціалізацію до нульового посилання? Тоді можна використовувати
a = None
a
визначеним або як, object()
або None
тому, що в таких випадках a
немає простору імен, __dict__
і жоден атрибут не може бути доданий до a
подібного, наприклад a.x = 10
.
a = object(); a.foo = 'bar'
дає AttributeError: 'object' object has no attribute 'foo'
.
Усі запропоновані рішення є дещо незграбними.
Я знайшов спосіб, який не є хакі, але насправді відповідає оригінальному дизайну.
>>> 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'
Конструює новий порожній об'єкт Set . Якщо надано необов’язковий ітерабельний параметр, оновлює набір елементами, отриманими в результаті ітерації. Всі елементи, що містять ітерацію, повинні бути незмінними або перетворюватися на незмінну, використовуючи протокол, описаний у розділі Протокол для автоматичного перетворення в незмінний.
Приклад:
myobj = set()
for i in range(1,10): myobj.add(i)
print(myobj)
Можна використовувати
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')]
На мій погляд, найпростіший спосіб:
def x():pass
x.test = 'Hello, world!'