# 4:
Я никогда не использую атрибуты класса для инициализации атрибутов экземпляра по умолчанию (те, которые вы обычно вводите в __init__
). Например:
class Obj(object):
def __init__(self):
self.users = 0
и никогда:
class Obj(object):
users = 0
Почему? Потому что он несовместим: он не делает то, что вы хотите, когда вы назначаете что-либо, кроме инвариантного объекта:
class Obj(object):
users = []
приводит к тому, что список пользователей распределяется между всеми объектами, что в данном случае нежелательно. Смешивать их в атрибуты класса и присваивания в __init__
в зависимости от их типа сбивает с толку, поэтому я всегда помещаю их все в __init__
, что в любом случае мне кажется более понятным.
В остальном я обычно помещаю специфичные для класса значения внутри класса. Это не так много, потому что глобальные переменные являются «злыми» - они не так важны, как в некоторых языках, потому что они все еще ограничены модулем, если сам модуль не слишком большой - но если внешний код хочет получить к ним доступ, удобно иметь все соответствующие значения в одном месте. Например, в module.py:
class Obj(object):
class Exception(Exception): pass
...
и затем:
from module import Obj
try:
o = Obj()
o.go()
except o.Exception:
print "error"
Помимо того, что подклассы могут изменять значение (что не всегда требуется), это означает, что мне не нужно кропотливо импортировать имена исключений и кучу других вещей, необходимых для использования Obj. "из модуля импорта Obj, ObjException, ..." быстро становится утомительным.