Как узнать иерархию вложенных классов? - PullRequest
4 голосов
/ 27 ноября 2009

У меня есть такой код Python.

Файл с именем mymodule.py

class MyBase(object):
    pass

Файл с именем data.py

from mymodule import MyBase

class A:
    class NestA(MyBase):
        pass
    class NestB(MyBase):
        pass

class B:
    class NestA(MyBase):
        pass
    class NestB(MyBase):
        pass

если у меня есть a = A.NestA (не относится к классу, a не объект класса NestA, а сам класс), как мне узнать, к какой иерархии вложенных классов принадлежит? имя дает мне NestA, так что это не проблема. Я хочу выяснить, к какому внешнему классу относится NestA, то есть к классу А или к классу В. Как мне это сделать?

Ответы [ 3 ]

1 голос
/ 27 ноября 2009

Вы можете сделать это с помощью модуля проверки:

import inspect

a = A.NestA

print a in [x[1] for x in inspect.getmembers(A, inspect.isclass)]
print a in [x[1] for x in inspect.getmembers(B, inspect.isclass)]

Результат:

True
False

Добавление:

Если вы ничего не знаете о классах в модуле, вы можете вернуться и получить модуль.

# for each class in a's module...
for klass in inspect.getmembers(inspect.getmodule(a), inspect.isclass):
    # see if a is in that class
    if a in [x[1] for x in inspect.getmembers(klass[1], inspect.isclass)]:
        print a, "is a member of", klass[0]

Результат:

__main__.NestA is a member of A
0 голосов
/ 27 ноября 2009

То, что вы просите, является результатом плохого дизайна. Я советую вам переопределить ваше решение.

0 голосов
/ 27 ноября 2009

Вы можете сделать что-то подобное с программированием метакласса.

class SetOuterClassType(type):
    def __init__(cls, name, bases, attrs):
        for attrname, attrvalue in attrs.iteritems():
            if getattr(attrvalue, '__set_outerclass__', False):
                attrvalue.__outerclass__ = cls

class OuterClassSetter(object):
    __metaclass__ = SetOuterClassType

class MyBase(object):
    @classmethod
    def fullname(cls):
        if hasattr(cls,'__outerclass__'):
            return '%s.%s' % (
                cls.__outerclass__.__name__, cls.__name__ )
        else:
            return '%s' % cls.__name__


class A(OuterClassSetter):
    class NestA(MyBase):
        __set_outerclass__ = True
    class NestB(MyBase):
        __set_outerclass__ = True


class B(OuterClassSetter):
    class NestA(MyBase):
        __set_outerclass__ = True

    class NestB(MyBase):
        __set_outerclass__ = True

print A.NestA.fullname() # prints 'A.NestA'
print A.NestB.fullname() # prints 'A.NestB'
print B.NestA.fullname() # prints 'B.NestA'
print B.NestB.fullname() # prints 'B.NestB'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...