Mise à jour
Mise à jour de la base de données, veuillez patienter...
Site original : Sam & Max: Python, Django, Git et du cul
Pas une question que l’on se pose souvent, à moins d’avoir une lib qui expose une classe avec beaucoup d’introspection.
Ceci dit pour la culture G, je me suis dit que ça pourrait intéresser quelques geeks de savoir comment lister les enfants d’une classe, récursivement.
def subclasses(cls, _found=()): """ Retourne toutes les classes héritant d'une classe """ # On check que la classe est hérite bien de "object". # Utile uniquement pour un code 2.x qui utiliserait # des old style classes, qui n'ont pas "__subclasses__". if not isinstance(cls, type): raise TypeError('subclasses works only with new-style classes' ', not %s' % cls) # On va stocker les classes rencontrées dans un set # pour éviter les doublons car on peut tomber sur # un héritage en forme de diamant. _found = _found or set() try: subs = cls.__subclasses__() except TypeError: # Erreur levée si cls == type, petits vicieux subs = cls.__subclasses__(cls) for sub in subs: if sub not in _found: _found.add(sub) # Un appel récursif comme on les aimes subclasses(sub, _found) return _found
Pas très compliqué, donc, si on connait les piègeounets : ça ne marche pas sur les old syle classes, et il y a un traitement spécial pour type
. Celà dit, qui utilise encore des old styles classes ? Et franchement lister les héritiers de type
, à par pour satisfaire sa curiosité…
Aller, juste pour le fun, sur un virtualenv vierge:
for x in subclasses(object): print x ## <type 'callable-iterator'> ## <class '_abcoll.Sized'> ## <type 'exceptions.EOFError'> ## <class '_abcoll.Mapping'> ## <type 'exceptions.UnicodeWarning'> ## <type 'exceptions.IOError'> ## <type 'memoryview'> ## <type 'code'> ## <type 'exceptions.ImportWarning'> ## <type 'sys.flags'> ## <type 'iterator'> ## <class 'warnings.catch_warnings'> ## <type 'exceptions.Warning'> ## <type 'exceptions.EnvironmentError'> ## <type 'dict'> ## <class 'encodings.utf_8.IncrementalEncoder'> ## <type 'weakproxy'> ## <class '_abcoll.Iterator'> ## <type 'sys.version_info'> ## <type 'posix.stat_result'> ## <type 'frozenset'> ## <class 'codecs.CodecInfo'> ## <class 'zipimport.ZipImportError'> ## <type 'exceptions.StopIteration'> ## <type 'exceptions.ImportError'> ## <class 'site._Printer'> ## <type 'weakref'> ## <class '_abcoll.Sequence'> ## <type 'property'> ## <class 'encodings.utf_8.IncrementalDecoder'> ## <type 'imp.NullImporter'> ## <type 'exceptions.TypeError'> ## <type 'bytearray'> ## <type 'int'> ## <type 'exceptions.UnicodeTranslateError'> ## <type 'instance'> ## <type 'exceptions.BaseException'> ## <type 'exceptions.SyntaxWarning'> ## <type 'file'> ## <class '_abcoll.MappingView'> ## <class '_weakrefset._IterationGuard'> ## <type 'exceptions.UnicodeDecodeError'> ## <type 'classobj'> ## <type 'exceptions.UnicodeError'> ## <class 'abc.abstractproperty'> ## <type 'exceptions.DeprecationWarning'> ## <type 'complex'> ## <type 'set'> ## <type 'buffer'> ## <type 'generator'> ## <type 'exceptions.Exception'> ## <class 'codecs.IncrementalDecoder'> ## <type 'exceptions.UserWarning'> ## <type 'staticmethod'> ## <type 'exceptions.UnicodeEncodeError'> ## <class 'encodings.CodecRegistryError'> ## <class '_abcoll.MutableSequence'> ## <class '_abcoll.KeysView'> ## <type 'cell'> ## <type 'exceptions.StandardError'> ## <type 'enumerate'> ## <type 'exceptions.KeyboardInterrupt'> ## <type 'exceptions.BufferError'> ## <class 'warnings.WarningMessage'> ## <type 'EncodingMap'> ## <class 'codecs.BufferedIncrementalDecoder'> ## <type 'exceptions.ValueError'> ## <class '_abcoll.Set'> ## <type 'exceptions.MemoryError'> ## <type 'exceptions.SystemExit'> ## <type 'reversed'> ## <class '_abcoll.Hashable'> ## <type 'bool'> ## <type 'classmethod'> ## <type 'exceptions.ReferenceError'> ## <type 'exceptions.GeneratorExit'> ## <class '_abcoll.Container'> ## <class '_abcoll.ItemsView'> ## <type 'xrange'> ## <type 'exceptions.PendingDeprecationWarning'> ## <type 'basestring'> ## <type 'exceptions.SystemError'> ## <type 'exceptions.ZeroDivisionError'> ## <class 'site.Quitter'> ## <type 'long'> ## <type 'NotImplementedType'> ## <type 'super'> ## <type 'fieldnameiterator'> ## <class '_abcoll.Callable'> ## <class '_abcoll.MutableSet'> ## <type 'exceptions.ArithmeticError'> ## <class 'abc.ABCMeta'> ## <type 'exceptions.OverflowError'> ## <type 'exceptions.FutureWarning'> ## <type 'sys.float_info'> ## <type 'formatteriterator'> ## <type 'type'> ## <type 'exceptions.AssertionError'> ## <type 'traceback'> ## <type 'exceptions.FloatingPointError'> ## <type 'function'> ## <type 'instancemethod'> ## <type 'sys.long_info'> ## <type 'builtin_function_or_method'> ## <class 'signal.ItimerError'> ## <class 'site._Helper'> ## <type 'exceptions.LookupError'> ## <type 'wrapper_descriptor'> ## <type 'exceptions.KeyError'> ## <class '_abcoll.ValuesView'> ## <type 'slice'> ## <class '_weakrefset.WeakSet'> ## <type 'list'> ## <type 'exceptions.IndexError'> ## <type 'getset_descriptor'> ## <type 'posix.statvfs_result'> ## <type 'exceptions.SyntaxError'> ## <type 'frame'> ## <class 'codecs.BufferedIncrementalEncoder'> ## <type 'PyCapsule'> ## <type 'exceptions.IndentationError'> ## <type 'NoneType'> ## <type 'zipimport.zipimporter'> ## <type 'member_descriptor'> ## <type 'exceptions.AttributeError'> ## <type 'ellipsis'> ## <type 'exceptions.UnboundLocalError'> ## <type 'unicode'> ## <class '_abcoll.Iterable'> ## <type 'exceptions.TabError'> ## <type 'exceptions.NameError'> ## <type 'tuple'> ## <class 'warnings._OptionError'> ## <type 'exceptions.NotImplementedError'> ## <type 'exceptions.RuntimeWarning'> ## <type 'str'> ## <class '_abcoll.MutableMapping'> ## <type 'exceptions.BytesWarning'> ## <type 'module'> ## <type 'exceptions.RuntimeError'> ## <class 'codecs.IncrementalEncoder'> ## <type 'float'> ## <type 'exceptions.OSError'> ## <type 'dictproxy'> ## <type 'weakcallableproxy'>
Putain, ça c’est du remplissage ! 20minutes serait fier de moi.