Класс Python по сравнению с атрибутами модуля

Одна из хороших вещей [приблизительно 110] - то, что можно выполнить ее как подпроцесс и проанализировать вывод.

Мы делаем это в нашем сценарии развертывания - работы как очарование.

13
задан 5 revs, 2 users 60% 23 May 2017 в 12:03
поделиться

4 ответа

№ 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, ..." быстро утомляет.

7
ответ дан 2 December 2019 в 00:31
поделиться

что является хорошим вариантом использования атрибутов класса

Случай 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 __ в зависимости от семантики.
  • Глобальная структура данных --- переходит в класс, если используется только классом, но может также переходить в модуль, в любом случае она должна быть очень хорошо документирована.
4
ответ дан 2 December 2019 в 00:31
поделиться

Инкапсуляция - хороший принцип: когда атрибут находится внутри класса, к которому он относится, а не в глобальной области, это дает дополнительную информацию людям, читающим код.

В ваших ситуациях 1–4, я бы по возможности избегал глобальных переменных и предпочел бы использовать атрибуты класса, позволяющие извлечь выгоду из инкапсуляции.

1
ответ дан 2 December 2019 в 00:31
поделиться

Атрибуты класса часто используются для отмены значений по умолчанию в подклассах. Например, BaseHTTPRequestHandler имеет константы класса sys_version и server_version, последняя по умолчанию равна «BaseHTTP /» + __version __ . SimpleHTTPRequestHandler заменяет server_version на «SimpleHTTP /» + __version __ .

2
ответ дан 2 December 2019 в 00:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: