2009-11-27 2 views
4

У меня такой код на 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.NestA (не это имеет в виду класс, а не является объектом класса NestA, но сам класс), как я могу узнать, в чем состоит вложенная иерархия классов? а. имя дает мне NestA, так что это не проблема. Я хочу узнать, какой внешний класс NestA является частью, то есть классом A или классом B. Как мне это сделать?

ответ

1

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

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

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

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' 
0

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

+0

Не обязательно. Вот что такое интроспекция. ОП не дал подробностей о дизайне, но я могу представить случаи, когда это было бы действительно. –

Смежные вопросы