2013-08-18 12 views

Odpowiedz

21

inspect modułu może pomóc, a konkretnie getclasstree() funkcja:

Umów daną listę klas w hierarchii zagnieżdżonych list. Gdzie pojawia się lista zagnieżdżona, zawiera klasy pochodzące z klasy , której wpis bezpośrednio poprzedza listę.

inspect.getclasstree(inspect.getmro(Exception)) 

Albo można rekursywnie przejść przez __subclasses__() przez drzewa dziedziczenia, tak:

def classtree(cls, indent=0): 
    print '.' * indent, cls.__name__ 
    for subcls in cls.__subclasses__(): 
     classtree(subcls, indent + 3) 

classtree(BaseException) 

drukuje:

BaseException 
... Exception 
...... StandardError 
......... TypeError 
......... ImportError 
............ ZipImportError 
......... EnvironmentError 
............ IOError 
............... ItimerError 
............ OSError 
......... EOFError 
......... RuntimeError 
............ NotImplementedError 
......... NameError 
............ UnboundLocalError 
......... AttributeError 
......... SyntaxError 
............ IndentationError 
............... TabError 
......... LookupError 
............ IndexError 
............ KeyError 
............ CodecRegistryError 
......... ValueError 
............ UnicodeError 
............... UnicodeEncodeError 
............... UnicodeDecodeError 
............... UnicodeTranslateError 
......... AssertionError 
......... ArithmeticError 
............ FloatingPointError 
............ OverflowError 
............ ZeroDivisionError 
......... SystemError 
............ CodecRegistryError 
......... ReferenceError 
......... MemoryError 
......... BufferError 
...... StopIteration 
...... Warning 
......... UserWarning 
......... DeprecationWarning 
......... PendingDeprecationWarning 
......... SyntaxWarning 
......... RuntimeWarning 
......... FutureWarning 
......... ImportWarning 
......... UnicodeWarning 
......... BytesWarning 
...... _OptionError 
... GeneratorExit 
... SystemExit 
... KeyboardInterrupt 
0

Reuse kod z biblioteki standardowej zamiast przetaczać własne.

import inspect 
import pydoc 

def print_class_hierarchy(classes=()): 
    td = pydoc.TextDoc() 
    tree_list_of_lists = inspect.getclasstree(classes) 
    print(td.formattree(tree_list_of_lists, 'NameSpaceName')) 

Aby to wykorzystać, musimy hierarchię klas, w formie wykazu, który ma sens dla nas, aby przekazać naszą funkcję. Możemy zbudować to przez rekursywnie przeszukiwania klas .__subclasses__() wyniki metody, przy użyciu tej funkcji (which I'll keep the canonical version of here):

def get_subclasses(cls): 
    """returns all subclasses of argument, cls""" 
    if issubclass(cls, type): # not a bound method 
     subclasses = cls.__subclasses__(cls) 
    else: 
     subclasses = cls.__subclasses__() 
    for subclass in subclasses: 
     subclasses.extend(get_subclasses(subclass)) 
    return subclasses 

Put to razem:

list_of_classes = get_subclasses(int) 
print_class_hierarchy(list_of_classes) 

która drukuje (w Pythonie 3):

>>> print_class_hierarchy(classes) 
builtins.int(builtins.object) 
    builtins.bool 
    enum.IntEnum(builtins.int, enum.Enum) 
     inspect._ParameterKind 
     signal.Handlers 
     signal.Signals 
    enum.IntFlag(builtins.int, enum.Flag) 
     re.RegexFlag 
    sre_constants._NamedIntConstant 
    subprocess.Handle 
enum.Enum(builtins.object) 
    enum.IntEnum(builtins.int, enum.Enum) 
     inspect._ParameterKind 
     signal.Handlers 
     signal.Signals 
enum.Flag(enum.Enum) 
    enum.IntFlag(builtins.int, enum.Flag) 
     re.RegexFlag 

Daje nam to drzewo wszystkich podklas, a także powiązane klasy dziedziczenia wielokrotnego - i podaje nam moduły, w których się znajdują.