Во-первых: я не вижу, как вложенные классы могут вам пригодиться. Как только у вас есть экземпляр f
из Foo
, вы понимаете, что f.Bar
и f.AnotherBar
будет одним и тем же объектом для всех экземпляров? То есть - вы не можете записать какой-либо атрибут, специфичный для f
, на f.Bar
, например f.Bar.speed
- или он столкнется с атрибутом из другого экземпляра g.Bar.speed
.
Чтобы преодолеть это и, фактически, единственное, что имеет смысл, вам нужно иметь экземпляры Bar
и AnotherBar
, прикрепленные к экземпляру f
. Эти экземпляры обычно не могут быть объявлены в классе класса - вы должны создать их в своем методе Foo __init__
.
Единственное, что могут сделать Bar и AntherBar: (1) иметь много классов и статических методов, то они работают только как пространства имен.
Или, если метаклассом для SuperBar
или сами реализуют протокол дескриптора - https://docs.python.org/3/reference/datamodel.html#implementing-descriptors - но их, вы бы гораздо лучше, если superbar
сам будет осуществлять дескриптор prootocol (при наличии либо __get__
или __set__
методы), и прилагается к Тело Foo у вас было бы экземпляров этих классов, а не самих классов.
Сказанное: вы пришли с решением использовать __dict__
для получения внутренних классов: это не сработает, если Foo
сам наследует от других классов, которые также имеют вложенные классы. Суперклассы Foo
никогда не искали. Вы можете иметь метод, либо посмотреть на все классы на Foo-х __mro__
, или просто использовать dir
и issubclass
:
class Foo:
@classmethod
def inner_classes_list(cls):
results = []
for attrname in dir(cls):
obj = getattr(cls, attrname)
if isinstance(obj, type) and issubclass(obj, SuperBar):
results.append(obj)
return results
(Если вы хотите, чтобы это работало для всех классов, как Foo, который не разделяет общую базу, тот же код будет работать, если он не будет объявлен как метод класса, конечно, а также, SuperBar
может быть параметром для этой функции, если у вас более одной иерархии вложенного класса.)
Теперь у вас есть это, мы просим вас задать другие вопросы, говоря, что вы хотите на самом деле - и прочитать о «дескрипторах» - и даже «свойствах». Действительно: очень мало пользы, которую можно придумать для вложенных подклассов.
1. Почему вы участвуете в занятиях, не могли бы вы дать больше контекста? 2. Разве вы просто не хотите, чтобы все подклассы «SuperBar» (в этом случае см. Http://stackoverflow.com/q/3862310/3001761)? – jonrsharpe
Этого недостаточно. В фактическом приложении у меня больше корневых классов, таких как 'Foo', с большим количеством внутренних классов для завершения дерева синтаксического анализа. Мне также необходимо обеспечить, чтобы определенный токен, найденный (например, «Бар»), приходил в контексте корневого токена 'Foo'. Чтобы захватить эту иерархию, я использую эти внутренние классы. - спасибо –
Тогда отредактируйте, чтобы больше контекста. Возможно, вы пытаетесь решить полностью неправильную проблему. – jonrsharpe