Pergunta

Se eu tiver código Python

class A():
    pass
class B():
    pass
class C(A, B):
    pass

e eu tenho aula C, existe uma maneira de iterar através de sua superclasse (A e B)?Algo como pseudocódigo:

>>> magicGetSuperClasses(C)
(<type 'A'>, <type 'B'>)

Uma solução parece ser inspecionar módulo e getclasstree função.

def magicGetSuperClasses(cls):
    return [o[0] for o in inspect.getclasstree([cls]) if type(o[0]) == type]

mas esta é uma maneira "Pythoniana" de atingir o objetivo?

Foi útil?

Solução

C.__bases__ é um array de superclasses, então você poderia implementar sua função hipotética assim:

def magicGetSuperClasses(cls):
  return cls.__bases__

Mas imagino que seria mais fácil apenas fazer referência cls.__bases__ diretamente na maioria dos casos.

Outras dicas

@John:Seu snippet não funciona. Você está retornando o aula das classes base (que também são conhecidas como metaclasses).Você realmente só quer cls.__bases__:

class A: pass
class B: pass
class C(A, B): pass

c = C() # Instance

assert C.__bases__ == (A, B) # Works
assert c.__class__.__bases__ == (A, B) # Works

def magicGetSuperClasses(clz):
  return tuple([base.__class__ for base in clz.__bases__])

assert magicGetSuperClasses(C) == (A, B) # Fails

Além disso, se você estiver usando Python 2.4+, você pode usar expressões geradoras em vez de criar uma lista (via []) e depois transformá-la em uma tupla (via tuple).Por exemplo:

def get_base_metaclasses(cls):
    """Returns the metaclass of all the base classes of cls."""
    return tuple(base.__class__ for base in clz.__bases__)

Esse é um exemplo um tanto confuso, mas genexps geralmente são fáceis e legais.:)

O módulo de inspeção foi um bom começo, use o getmro função:

Retorna uma tupla das classes base da classe cls, incluindo cls, na ordem de resolução do método.Nenhuma classe aparece mais de uma vez nesta tupla....

>>> class A: pass
>>> class B: pass
>>> class C(A, B): pass
>>> import inspect
>>> inspect.getmro(C)[1:]
(<class __main__.A at 0x8c59f2c>, <class __main__.B at 0x8c59f5c>)

O primeiro elemento da tupla retornada é C, você pode simplesmente desconsiderá-lo.

se você precisar saber em qual ordem super() chamaria as classes que você pode usar C.__mro__ e não precisa inspect portanto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top