Структурные объекты в python

Я хотел создать объект «struct», чтобы сохранить различные флаги статуса. Мой первый подход – это (стиль javascript)

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

Определенно не то, что я ожидал, потому что это работает:

 >>> class Anon: pass ... >>> b=Anon() >>> b.foo = 4 

Я думаю, это потому, что объект () не имеет __dict__ . Я не хочу использовать словарь и предполагаю, что я не хочу создавать объект Anon, есть ли другое решение?

  • Заменить часть строки в Python?
  • Автоимпорт Python
  • Метод расширения для встроенных типов python!
  • Как запустить Spyder в виртуальной среде?
  • Python номера игра обратная
  • Идиома для выравнивания мелкого вложенного списка: как это работает?
  • поставщик google app engine oauth2
  • __init __ () принимает ровно 3 аргумента (1 данный)
  • 8 Solutions collect form web for “Структурные объекты в python”

    Наиболее кратким способом сделать «общий объект, которому вы можете назначить / получить атрибуты», вероятно, является:

     b = lambda:0 

    Как видно из большинства других ответов, существует много других способов, но трудно выполнить это для краткости ( lambda:0 – это точно такое же количество символов, как object() … ;-).

    Из официальной документации Python :

    9,7. Коэффициенты и окончания

    Иногда бывает полезно иметь тип данных, похожий на «запись» Pascal или C «struct», объединяющую несколько названных элементов данных. Пустое определение класса будет хорошо выполнено:

     class Employee: pass john = Employee() # Create an empty employee record # Fill the fields of the record john.name = 'John Doe' john.dept = 'computer lab' john.salary = 1000 

    Это кажется естественным и простым: Pythonic. Помните Дзэн! «Простой лучше, чем сложный» (номер 3) и «Если внедрение легко объяснить, это может быть хорошей идеей» (номер 11)

    Кроме того, struct – это не что иное, как class с публичными членами (т. struct{}; и class{public:}; – это то же самое (в, например, C ++)). Разве вы не должны рассматривать это и избегать искусственных конструкций в своей программе Python? Python должен быть читабельным, удобным и понятным.

    У меня был один и тот же вопрос. Я спросил его в списке рассылки, и Алекс Мартелли отметил, что object является основой всего наследования в Python; если object() создал экземпляр класса со своим собственным словарем, тогда у каждого объекта на Python должен был быть свой собственный словарь, и это потеряло бы память. Например, True и False являются объектами; ясно, что они не нуждаются в собственных словарях!

    Я был бы рад, если бы была какая-то встроенная функция Python, где я мог просто сказать:

     x = struct() x.foo = 1 x.bar = 2 

    Но тривиально написать struct() :

     class struct(object): pass 

    Или вы можете сделать несколько более сложный:

     class struct(object): def __init__(self, **kwargs): self.__dict__.update(kwargs) 

    Более сложный позволяет сделать это:

     x = struct(foo=1, bar=2) print(x.foo) # prints 1 print(x.bar) # prints 2 x.baz = 3 print(x.baz) # prints 3 

    Но так сложно написать struct() что, я думаю, это не считалось целесообразным добавить к языку. Может быть, нам стоит нажать на стандартную функцию, добавленную в модуль collections или что-то в этом роде.

    Я лично считаю, что самое чистое решение – это то, что вы уже догадались:

     class Scratch(object): pass s = Scratch() s.whatever = 'you want' 

    Я знаю, что ты сказал, что не хочешь __dict__ , но это меня смущает, поскольку я не вижу причины заботиться об этом. Вам не нужно ссылаться на __dict__ , то есть внутреннюю деталь реализации Python. В любом случае, любой экземпляр на Python, который позволяет динамически добавлять атрибуты, будет иметь __dict__ потому что именно так Python выполняет динамические атрибуты. Даже если экземпляр создан действительно умным способом, он будет иметь __dict__ .

    Если вы еще этого не сделали, я рекомендую прочитать PEP 20 и PEP 8 (нет репутации, поэтому для меня есть только одна ссылка.) Не то, чтобы PEP напрямую касались вашего вопроса, но я думаю, что полезно использовать Python в Питоновская манера.

    Попробуй это

     >>> status=type('status',(object,),{})() >>> status.foo=3 >>> status.foo 3 

    Вам не нужно указывать имя класса, если вы не хотите

     >>> status=type('',(object,),{})() >>> status.__class__.__name__ '' 

    Тайна здесь – разница между объектами и экземплярами класса .

    В Python все является объектом. Классы – это объекты, целые – это объекты, типы – это объекты, а экземпляры классов – объекты. Когда вы говорите object() вы получаете простой объект базового уровня. Ничего. Совершенно бесполезно. Более низкий уровень, чем что-либо еще, что вы можете использовать в Python.

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

     class MyClass(object): pass 

    object фактически является типом (например, как str и int являются типами). Когда вы вызываете object() вы не создаете экземпляр класса, создавая экземпляр специального типа объекта. Но в случае object это особенно важно, насколько это абсолютно очевидно .

    Только экземпляры классов обладают особой способностью делать точечные нотации. Это не общее свойство всех объектов. Представьте, если бы это было так! Вы могли бы делать сумасшедшие вещи, такие как добавление свойств к строкам:

     s = "cat" s.language = "english" 

    Очевидно, вы не можете этого сделать.

    Конечно, всегда есть namedtuple . Это дешево и быстро, но неизменно – вы должны знать свои имена атрибутов и значения заранее, и вы не можете изменить их значения позже. Но по крайней мере у него есть атрибуты атрибутов struct / object. И он будет работать с Python 2 и 3

     >>> from collections import namedtuple >>> Status = namedtuple('Status', 'a b') >>> s = Status(a=1, b=2) >>> sa + sb 3 

    Если вам нужна семантика объекта Javascript, вы можете рассмотреть возможность использования библиотеки пространств имен . Вам просто нужно сначала pip install namespaces .

     >>> import namespaces as ns >>> b = ns.Namespace() >>> b.foo = 4 >>> b Namespace(foo=4) 

    полная оговорка: я являюсь автором библиотеки namespaces .

    Python - лучший язык программирования в мире.