Сообщить об ошибке.

Класс Python как структура, подобная языку C

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

Самый простой вариант создание структуры подобной C - это создание структуры из пустого объявления класса!

Например:

class Employee:
    """Структура Employee"""
    pass

# Создаем пустую структуру
john = Employee()
# Заполняем члены структуры `Employee`
>>> john.name = 'John Doe'
>>> john.dept = 'computer lab'
>>> john.salary = 1000
# Доступ к членам структуры `Employee`
>>> john.dept
# 'computer lab'

# Изменение членов структуры `Employee`
>>> john.salary = 1500
>>> john.salary
# 1500

Или можно использовать объявление класса с атрибутом __slots__. Атрибут __slots__ призван уменьшить накладные расходы памяти, а так же он может ускорить доступ к атрибутам.

Небольшое предостережение: необходимо только один раз объявлять определенный слот в дереве наследования.

class Employee:
    __slots__ = ['name', 'dept', 'salary']

# Создаем пустую структуру
>>> john = Employee()
# Заполняем члены структуры `Employee`
>>> john.name = 'John Doe'
>>> john.dept = 'computer lab'
>>> john.salary = 1000
# Доступ к членам структуры `Employee`
>>> john.name
# 'John Doe'

# Изменение членов структуры `Employee`
>>> john.salary = 1500
>>> john.salary
# 1500

Классы в Python могут иметь связанные с ним функции, которые работают только с экземпляром класса, тогда как в языке C, функция, которая хочет работать со структурой, должна каким-то образом принимать структуру в качестве параметра, обычно с помощью указателя. Следовательно, фрагменту кода Python, который ожидает определенный абстрактный тип данных, можно передать классу, который эмулирует методы этой структуры.

Например, если есть функция, которая форматирует некоторые данные из объекта file, то можно определить класс с методами read() и readline(), которые будут получать данные из строкового буфера и передавать их в качестве аргумента.

Объекты метода экземпляра созданной структуры, также будут имеют атрибуты: m.__self__ - это объект структуры с методом .m(), а m.__func__ объект функции, соответствующий методу.

Второй вариант объявления структуры данных, подобной языку C - это создание пользовательского типа данных при помощи встроенного модуля dataclasses, который доступен с версии Python 3.7.

from dataclasses import dataclass

@dataclass
class Employee():
    """Тип данных Employee"""
    name: str = None
    dept: str = None
    salary: int = 0

>>> john = Employee('John Doe', 'computer lab', 1000)
>>> john
# Employee(name='John Doe', dept='computer lab', salary=1000)
>>> john.salary
# 1000
>>> john.salary = 1500
>>> john.salary
# 1500

Третий вариант объявления структуры - это использовать встроенный модуль ctypes. Этот модуль представляет типы, совместимые с языком C. Для создания структур, используем его следующим образом:

from ctypes import *

# Объявляем структуру
class Employee(Structure):
    _fields_ = [
        ('name', c_wchar_p),
        ('dept', c_wchar_p),
        ('salary', c_int)
    ]

# Инициализируем члены структуры `Employee`
>>> john = Employee('John Doe', 'computer lab', 1000)
# Доступ к членам структуры `Employee`
>>> john.name
# 'John Doe'
>>> john.salary
# 1000

# Изменение членов структуры `Employee`
>>> john.salary = 1500
>>> john.salary
# 1500

Более подробно о создании структур, совместимые с языком C, смотрите материал "Структуры Structure и Union модуля ctypes в Python"

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

Пример:

>>> import collections
# Создаем структуру
>>> Employee = collections.namedtuple('Employee', ['name', 'dept', 'salary'])
# Заполняем члены структуры `Employee`
>>> john = Employee('John Doe', 'computer lab', 1000)
# смотрим 
>>> john
# Employee(name='John Doe', dept='computer lab', salary=1000)

# Доступ к членам структуры `Employee`
>>> john.name
'John Doe'
>>> john.salary
1000