Есть ли смысл определять класс внутри другого класса в Python?
То, о чем я говорю, это вложенные классы. По сути, у меня есть два класса, которые я моделирую. Класс DownloadManager и класс DownloadThread. Очевидная концепция ООП - это композиция. Однако состав не обязательно означает вложенность, правильно?
У меня есть код, который выглядит примерно так:
class DownloadThread:
def foo(self):
pass
class DownloadManager():
def __init__(self):
dwld_threads = []
def create_new_thread():
dwld_threads.append(DownloadThread())
Но теперь мне интересно, есть ли ситуация, когда гнездование будет лучше. Что-то вроде:
class DownloadManager():
class DownloadThread:
def foo(self):
pass
def __init__(self):
dwld_threads = []
def create_new_thread():
dwld_threads.append(DownloadManager.DownloadThread())
Ответы
Ответ 1
Возможно, вы захотите сделать это, когда "внутренний" класс является одноразовым, который никогда не будет использоваться вне определения внешнего класса. Например, для использования метакласса иногда бывает удобно делать
class Foo(object):
class __metaclass__(type):
....
вместо определения метакласса отдельно, если вы используете его только один раз.
Единственный раз, когда я использовал вложенные классы, я использовал внешний класс только как пространство имен, чтобы группировать связку тесно связанных между собой классов:
class Group(object):
class cls1(object):
...
class cls2(object):
...
Затем из другого модуля вы можете импортировать Group и ссылаться на них как на Group.cls1, Group.cls2 и т.д. Однако можно утверждать, что вы можете сделать то же самое (возможно, менее запутанным образом) с помощью модуля.
Ответ 2
Я не знаю Python, но ваш вопрос кажется очень общим. Игнорируйте меня, если это относится к Python.
Вложенность классов - это область. Если вы считаете, что один класс будет иметь смысл только в контексте другого, то первый, вероятно, хороший кандидат, чтобы стать вложенным классом.
Это обычный шаблон, создающий классы-помощники как частные, вложенные классы.
Ответ 3
Вы можете использовать класс как генератор классов. Например (в некоторых случаях код манжеты:)
class gen(object):
class base_1(object): pass
...
class base_n(object): pass
def __init__(self, ...):
...
def mk_cls(self, ..., type):
'''makes a class based on the type passed in, the current state of
the class, and the other inputs to the method'''
Я чувствую, что, когда вам нужна эта функциональность, вам будет очень ясно. Если вам не нужно делать что-то похожее, чем это, вероятно, не очень полезно.
Ответ 4
Для этого нет никакой пользы, кроме случаев, когда вы имеете дело с метаклассами.
класс: suite действительно не то, что вы думаете. Это странный масштаб, и это странные вещи. Это действительно даже не класс! Это всего лишь способ сбора некоторых переменных - имя класса, базы, небольшой словарь атрибутов и метакласс.
Имя, словарь и базы все передаются функции, которая является метаклассом, а затем она назначается переменной "имя" в области, где был класс: suite.
То, что вы можете получить, возившись с метаклассами, а также с помощью гнездования классов в ваших стандартных стандартных классах, сложнее читать код, сложнее понять код и нечетные ошибки, которые трудно понять, не будучи глубоко знакомы с тем, почему Область "класс" полностью отличается от любой другой области python.
Ответ 5
Нет, состав не означает гнездование.
Было бы разумно иметь вложенный класс, если вы хотите скрыть его больше в пространстве имен внешнего класса.
Во всяком случае, я не вижу практического использования для гнездования в вашем случае. Это сделало бы код более трудным для чтения (понимания), и это также увеличит отступ, который сделает линии более короткими и более склонными к расщеплению.