Можно ли сделать все входные данные для класса .__ init __ () как атрибуты в одной строке? - PullRequest
0 голосов
/ 11 июля 2019

Большинство классов Python, которые я видел, выглядят так (из учебника):

class Person:

    def __init__(self, name, surname, birthdate, address, telephone, email):
        self.name = name
        self.surname = surname
        self.birthdate = birthdate

        self.address = address
        self.telephone = telephone
        self.email = email

Есть ли способ получить все входные данные для init в качестве атрибутов, не вводя их по одному построчно?

Это не только для хранения данных, и у меня есть другие методы внутри класса.

Мне нравится делать что-то вроде этого:

class A:
    def __init__(self, name, surname, birthdate, address, telephone, email):
        for name, value in kwargs.items():
            setattr(self, name, value)

Таким образом, класс не может быть инициирован какой-либо случайной переменной, но тогда я не набираю self.item = item для каждого элемента.

Ответы [ 2 ]

2 голосов
/ 11 июля 2019

Для позиционных аргументов вы можете сделать что-то вроде

class A:
    def __init__(self, *args):
        names = ('attr_name_1', 'attr_name_2', ..., 'attr_name_n')
        for name, value in zip(names, args):
            setattr(self, name, value)

Если вы хотите убедиться, что получаете необходимое вам количество значений, вы можете проверить len(args) == len(names)

С аргументами ключевых слов это просто

class A:
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)

Опять же, если вы хотите проверить, соответствуют ли аргументы ожидаемым, вы можете сохранить ожидаемые ключи в наборе (скажем, names) и проверить names == set(kwargs.keys())

В любом случае, если вы хотите использовать свой класс для хранения этих данных, вы можете использовать dataclasses. Взято из официальной документации Python3.7:

@dataclass
class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand

Обратите внимание, что для более ранних версий Python dataclasses не является частью стандартной библиотеки Python, но может быть установлен как обычный пакет (например, pip install dataclasses)

0 голосов
/ 11 июля 2019

Кажется, это один из вариантов (возможно, не самый питонический способ):

class A:
    def __init__(self, name, surname):
        for item in inspect.signature(A).parameters:
            setattr(self, item, eval(item))

С учетом вышесказанного, имя и фамилия должны быть предоставлены при инициации класса, но мне не нужновыполнять задание в init () по одной строке за раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...