Python переменные экземпляра - PullRequest
0 голосов
/ 10 апреля 2020

При объявлении переменных экземпляра класса, можете ли вы использовать вызов одного из методов класса для инициализации одной из переменных экземпляра в вашем конструкторе? Например, допустим, у меня был класс Button и метод в этом классе methodA (), который установил для переменной с именем 'active' значение False. Могу ли я инициализировать 'active' с помощью вызова метода?

class Button:
    def __init__(self):
        *snip*
        self.methodA()

    def methodA(self):
        self.active = False

Будет ли этот метод правильным для инициализации моей переменной экземпляра 'active'?

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

Да, это может быть сделано. Фактически, в Python любой нестатический метод c может инициализировать новые члены данных для объектов класса. Однако рекомендуется всегда инициализировать элементы в __init__(), потому что считается хорошей практикой инициализировать используемые элементы при создании объекта и инициализации.

0 голосов
/ 11 апреля 2020

С контекстом, добавленным в ваш комментарий, ваш вопрос имеет больше смысла. Да, вы можете установить любой атрибут объекта в другом методе. На самом деле, из-за динамического набора Python c вы можете установить их даже после ваш объект был инициализирован:

class Example:
    pass

e = Example()
e.foo = 'bar'
e.foo  # returns 'bar'

Как правило, однако, вы хотите инициализировать все атрибуты объекта в его методе __init__, потому что его легче поддерживать, и вы всегда знаете, где искать, когда не помните, определен ли определенный атрибут или откуда он взят.

В В вашем примере имеет смысл инициализировать ваш класс всеми атрибутами, которые у него когда-либо будут, и затем вызывать методы для их изменения. Например:

class Button:
    def __init__(self):
        *snip*
        self.active = False
        self.color = 'red'
        self.linewidth = 2

    def activate(self):
        self.active = True
        self.color = 'green'
        self.linewidth = 5

    def deactivate(self):
        self.active = False
        self.color = 'red'
        self.linewidth = 2

Теперь вы, вероятно, заметили, что у нас есть дублирование кода - метод __init__ в основном копирует строки в методе deactivate! Тем не менее, удобство чтения имеет все атрибуты в методе __init__. Что мы делаем?

Рассмотрим этот компромисс: инициализируем все атрибуты значениями None, а затем вызываем метод deactivate:

 class Button:
    def __init__(self):
        *snip*
        self.active = None
        self.color = None
        self.linewidth = None
        self.deactivate()

    def activate(self):
        self.active = True
        self.color = 'green'
        self.linewidth = 5

    def deactivate(self):
        self.active = False
        self.color = 'red'
        self.linewidth = 2

Это объединяет лучшее из обоих миров: наш код читабелен (метод __init__ в основном читает «инициализировать кнопку с этими атрибутами и затем деактивировать ее»), но также не страдает от дублирования кода.

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

...