Одна из хороших вещей [приблизительно 110] - то, что можно выполнить ее как подпроцесс и проанализировать вывод.
Мы делаем это в нашем сценарии развертывания - работы как очарование.
№ 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. "from module import Obj, ObjException, ..." быстро утомляет.
Мне нужно кропотливо импортировать имена исключений и множество других вещей, необходимых для использования Obj. "from module import Obj, ObjException, ..." быстро утомляет. Мне нужно кропотливо импортировать имена исключений и множество других вещей, необходимых для использования Obj. "from module import Obj, ObjException, ..." быстро утомляет.что является хорошим вариантом использования атрибутов класса
Случай 0. Методы класса - это просто атрибуты класса. Это не просто техническое сходство - вы можете получать доступ и изменять методы класса во время выполнения, назначая им вызываемые объекты.
Случай 1. Модуль может легко определить несколько классов. Разумно инкапсулировать все, что касается класса A
, в A ...
и все о классе B
в B ...
. Например,
# module xxx
class X:
MAX_THREADS = 100
...
# main program
from xxx import X
if nthreads < X.MAX_THREADS: ...
Случай 2. Этот класс имеет множество атрибутов по умолчанию, которые можно изменить в экземпляре. Здесь возможность оставить атрибут «глобальным по умолчанию» - это особенность, а не ошибка.
class NiceDiff:
"""Formats time difference given in seconds into a form '15 minutes ago'."""
magic = .249
pattern = 'in {0}', 'right now', '{0} ago'
divisions = 1
# there are more default attributes
Один создает экземпляр NiceDiff для использования существующего или слегка измененного форматирования, но локализатор для другого языка подклассы класса для реализации некоторых функций принципиально другим способом и переопределяют константы:
class Разница(NiceDiff): # NiceDiff localized to Russian
'''Из разницы во времени, типа -300, делает конкретно '5 минут назад'.'''
pattern = 'через {0}', 'прям щас', '{0} назад'
Ваш case :
self.CONSTANT = ...
, поэтому я не вижу большого риска их заткнуть. __ init __
в зависимости от семантики. Инкапсуляция - хороший принцип: когда атрибут находится внутри класса, к которому он относится, а не в глобальной области, это дает дополнительную информацию людям, читающим код.
В ваших ситуациях 1–4, я бы по возможности избегал глобальных переменных и предпочел бы использовать атрибуты класса, позволяющие извлечь выгоду из инкапсуляции.
Атрибуты класса часто используются для отмены значений по умолчанию в подклассах. Например, BaseHTTPRequestHandler имеет константы класса sys_version и server_version, последняя по умолчанию равна «BaseHTTP /» + __version __
. SimpleHTTPRequestHandler заменяет server_version на «SimpleHTTP /» + __version __
.