Я начну с описания дилеммы, с которой я сейчас сталкиваюсь. У меня есть класс (назовем его NeatClass
). У него есть несколько атрибутов экземпляра, все из которых я, как обычно, объявляю в методе __init__()
класса. Я добавляю в класс новый метод (назовем его util_method()
), и он требует сохранения внутреннего состояния между вызовами. Я намерен сохранить это состояние в атрибуте экземпляра (назовем его self._util_attr
).
Теперь, согласно обычным правилам, я должен объявить self._util_attr
внутри NeatClass.__init__()
:
class NeatClass:
def __init__():
self.attr1 = ...
self.attr2 = ...
# ...
self._util_attr = None # type: ignore
Я понимаю, что объявление атрибутов экземпляра внутри __init__()
должно повысить читаемость кода (см. this и это ТАК вопросы) - полностью с этим согласен. Однако в моем случае это может иметь противоположный эффект. Вот почему:
- В моем классе только
util_method()
должен использоватьself._util_attr
. - Хотя я хочу, чтобы
util_method
был частью API моего класса, он будет использоваться только в некоторых редких случаях (большинство экземпляровNeatClass
вообще не будут использовать этот метод). - Я использую
mypy
для ввода своего кода. Во время вызоваNeatClass.__init__()
типself._util_attr
неизвестен (отсюда комментарий# type: ignore
). По причинам, выходящим за рамки этого вопроса, я не могу использоватьUnion
или что-то в этом роде для указания типа этой переменной.
Итак, что я действительно хочу сделать, так это:
class NeatClass:
def __init__():
self.attr1 = ...
self.attr2 = ...
# ...
def util_method(self):
if not hasattr(self, "_util_attr"):
self._util_attr = ... # initial value of the variable
# ...
Однако я хочу, чтобы мой код соответствовал как PEP8, так и Руководство по стилю Google Python. Итак, я искал в обоих рекомендациях ссылки на ситуации, в которых допустимо объявление атрибута экземпляра за пределами __init__()
. Как вы могли догадаться, я ничего не нашел. На самом деле, я вообще ничего не нашел об объявлении атрибутов экземпляра внутри __init__()
, что действительно стало неожиданностью. Это привело нас к моему вопросу:
Есть ли какие-либо ситуации в общих правилах стиля Python (особенно PEP8 и Google), в которых допустимо объявлять атрибуты экземпляра за пределами __init__()__
?
Также приветствуются указатели на то, где в этих рекомендациях указано, что атрибуты экземпляра должны быть объявлены только внутри __init__()
. Также приветствуются предложения по рефакторингу моего кода.
Обратите внимание, что я не ищу мнения (что, в свою очередь, нарушило бы руководство StackOverflow). Я просто ищу ссылки на разделы наиболее распространенных рекомендаций по стилю Python, которые касаются описанной мной ситуации. Я также не думаю, что этот вопрос является дубликатом - я прочитал несколько других вопросов SO по этому вопросу, и ни один из них, похоже, не задавал то же самое, что и я здесь.
Спасибо за ваше время!
util_method()
должен использоватьself.util_attr
Тогдаutil_attr
, вероятно, должна быть локальной переменной - person DeepSpace   schedule 14.02.2021util_attr
на самом деле должно быть_util_attr
, то есть непубличным? Является лиutil_attr
своего рода кешем? - person MisterMiyagi   schedule 14.02.2021util_method
, поэтому оно не может быть локальной переменной. Если бы я использовал C, я думаю, это был бы прецедент для переменнойstatic
- person Talendar   schedule 14.02.2021NeatClass
должен иметь свой собственный кеш/внутреннее состояние (self._util_attr
), возможно, с очень разными значениями. Я думаю, это не было бы вариантом использования статических переменных, как я думал ранее, если бы я программировал на C. Извините, что не понял этого раньше - person Talendar   schedule 14.02.2021Any
? - person juanpa.arrivillaga   schedule 14.02.2021