Можно ли инициализировать поля объекта непосредственно как ключевые параметры __init__?

Когда я пишу класс, я часто делаю это:

class Bulbasaur:
  """Quite obviously, the best pokemon"""
  self __init__(self, n_potions = 0, berries = 0, nickname = '')
    self.n_potions = n_potions
    self.berries = berries
    self.nickname = nickname

Возможно, есть и другие способы справиться со следующим - если так, пожалуйста, укажите (!) - но это проще сделать:

class Bulbasaur:
  """Quite obviously, the best pokemon"""
  self __init__(self, self.n_potions = 0, self.berries = 0, self.nickname = '')
    pass

Где поля будут заполнены правильными значениями непосредственно из аргументов __init__ . Это возможно? Если нет, то в чем его недостаток? Если нет, есть ли лучший способ справиться с вышеупомянутым сценарием?

Всего 1 ответ


Это было намеренное дизайнерское решение в Python: не существует специального синтаксиса для определения атрибутов, которые должен иметь экземпляр, или для инициализации объекта после его создания. __init__ - это просто другой метод, хотя и тот, который вызывается в процессе создания экземпляра класса.

Классы данных, представленные в Python 3.7, позволяют сократить некоторые из шаблонов. Аннотированные переменные в теле оператора class используются для определения реализации по умолчанию __init__ (среди других специальных методов), которая выполняет то, что вы обычно хотите, а именно просто для установки атрибутов на основе аргументов для __init__ :

from dataclasses import dataclass


@dataclass
class Bulbasaur:
    n_potions: int = 0
    berries: int = 0
    nickname: str = ''


b1 = Bulbasaur()
assert b1.n_potions == 0 and b1.berries == 0 and b1.nickname == ''
b2 = Bulbasaur(3, 2, 'foo')
assert b2.n_potions == 3 and b2.berries == 2 and b2.nickname == 'foo'

Есть идеи?

10000