Страницы

Поиск по вопросам

среда, 3 октября 2018 г.

Можно ли как-нибудь упростить инициализацию классов на Python?

У меня есть конструктор класса примерно вот такого вида:
class A: def __init__(self, a1, a2, ..., an): self.a1 = a1 self.a2 = a2 ... self.an = an ...
Можно ли как-то упростить процесс инициализации, а то писать n повторяющихся строчек совсем не интересно.
UPD. Дополню вопрос: 1) Как быть в случае, когда присутствуют значения по умолчанию?
class B: def __init__(self, b1=b1_0, b2=b2_0, ..., bn=bn_0): self.b1 = b1 self.b2 = b2 ... self.bn = bn ...
2) Возможно ответ последует из п.1, но всё равно задам ещё один вопрос: Что делать, если для каких-то аргументов есть значение по умолчанию, а для каких-то нет?


Ответ

Если неизменяемый объект хотите создать, представляющий запись с полями, можно использовать collections.namedtuple
from collections import namedtuple
A = namedtuple("A", "a1 a2 an") A.__new__.__defaults__ = (0,) * 3 # set default values print(A(1, 2)) # -> A(a1=1, a2=2, an=0)
Для изменяемых объектов, можно использовать types.SimpleNamespace:
from types import SimpleNamespace
print(SimpleNamespace(a1=1, a2=2, an=3)) # -> namespace(a1=1, a2=2, an=3)
SimpleNamespace это простая альтернатива конструкции: class NS: pass, которая за вас __init__, __repr__, __eq__ методы определяет.
Чтобы указать типы, в неизменяемом случае, можно использовать typing.NamedTuple
from typing import NamedTuple
class B(NamedTuple): b1: str = '0' b2: int = 1
print(B()) # -> B(b1='0', b2=1) print(B(b2=3)) # -> B(b1='0', b2=3)
PEP 557 -- Data Classes (Python 3.7+) хочет ввести классы данных для случая «изменяемые namedtuple со значениями по умолчанию». Для предыдущих версий Питона, можно использовать неинтегрированную в стандартную библиотеку реализацию из dataclasses пакета
from dataclasses import dataclass # $ pip install dataclasses
@dataclass class B: b1: str = '0' b2: int = 1
print(B()) # -> B(b1='0',b2=1) b = B(b2=2) print(b) # -> B(b1='0',b2=2) b.b1 = '1' print(b) # -> B(b1='1',b2=2)
В более общем случае, можно воспользоваться attrs пакетом, который множество дополнительной функциональности предоставляет. См. ещё примеры в ответе на похожий вопрос: Как создать коллекцию объектов пользовательского класса?

Комментариев нет:

Отправить комментарий