Использование класса self.varname в аргументах __init__ - PullRequest
0 голосов
/ 21 марта 2020

Мне просто интересно, есть ли короткая рука python для инициализации переменных в классе. Я знаю, что:

class myclass():
    def __init__(self, a):
        self.a = a

работает, но мне было интересно, была ли короткая рука. Способ python3 уже делает это, вероятно, лучший, потому что он более гибок для различных типов __init__() методов, которые могут быть написаны, но мне интересно, есть ли способ сделать это, который короче выписать?

Я попытался использовать self.a в качестве аргумента для __init__(), и это не сработало.

Python 3.7.5rc1 (default, Oct  8 2019, 16:47:45) 
[GCC 9.2.1 20190909] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class myclass():
...     def __init__(self, self.a):
  File "<stdin>", line 2
    def __init__(self, self.a):
                           ^
SyntaxError: invalid syntax

Ничего страшного, если нет другого синтаксиса.

Ответы [ 2 ]

0 голосов
/ 21 марта 2020

Вы можете определить класс данных :

from dataclasses import dataclass


@dataclass
class MyClass():
    a: int   # A type is required; replace int with whatever type a should be

Декоратор заботится о генерации, среди прочего, метода __init__, который устанавливает self.a с заданным аргументом.

>>> x = MyClass(3)
>>> x.a
3
0 голосов
/ 21 марта 2020

Не существует эффективного ярлыка - это часть явной природы Python, которая должна явно создавать переменные вашего экземпляра, используя имена, которые вы хотите.

, если вы действительно настаиваете на более коротком коде, вы может использовать:

class MyClass:
      def __init__(self, a, b, c):
          self.__dict__.update(locals())

Все параметры (a, b & c) эффективно существуют как локальные переменные в методе __init__, поэтому вы можете напрямую обновить экземпляр __dict__; но

  • Этот фрагмент превращает все ваши параметры в атрибуты независимо от того, хотите вы их или нет
  • Вам нужен более сложный код, чтобы сделать атрибуты приватными - вам понадобится, например, понимание словаря - и ваш стиль имеет проблему выше.
  • Вам все еще нужно явно указать код, если какой-либо из ваших атрибутов на самом деле должен быть изменяемым типом (таким как списки, словари, наборы и т. д. c).
  • В итоге вы получите атрибут self.self (атрибут экземпляра, который будет ссылаться на себя); явно не очень хорошая идея. (Спасибо user2357112supportsMonica за определение этого).

Так что, хотя ярлык __dict__.update может выглядеть мило, это не очень хорошее решение; Есть слишком много общих случаев, которые просто не обрабатываются.

Редактировать: Вы можете использовать классы данных, если вы знаете, что все ваши атрибуты будут опубликованы c и, например, вы не хотите использовать свойства для обеспечить обертки вокруг ваших атрибутов. Классы данных могут решить ваши проблемы, но это может создать больше проблем в зависимости от вашего конкретного случая использования. Если все, что вы хотите сделать, это сохранить несколько строк кода в методе __init__, то я думаю, что вы делаете неправильную вещь - явное предпочтение перед неявным.

Я не совсем понимаю, что вы пытались добиться в вашем втором фрагменте - имена параметров для методов не могут быть точечными именами.

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