xticks barplot python python-datamodel

python - barplot - pandas plot



Obtener el nombre de clase totalmente calificado de un objeto en Python (9)

Para fines de registro, quiero recuperar el nombre de clase completamente calificado de un objeto de Python. (Con totalmente calificado me refiero al nombre de la clase, incluido el nombre del paquete y del módulo).

Sé acerca de x.__class__.__name__ , pero ¿hay un método simple para obtener el paquete y el módulo?


Algunas personas (por ejemplo, https://.com/a/16763814/5766934 ) argumentan que __qualname__ es mejor que __name__ . Aquí hay un ejemplo que muestra la diferencia:

$ cat dummy.py class One: class Two: pass $ python3.6 >>> import dummy >>> print(dummy.One) <class ''dummy.One''> >>> print(dummy.One.Two) <class ''dummy.One.Two''> >>> def full_name_with_name(klass): ... return f''{klass.__module__}.{klass.__name__}'' >>> def full_name_with_qualname(klass): ... return f''{klass.__module__}.{klass.__qualname__}'' >>> print(full_name_with_name(dummy.One)) # Correct dummy.One >>> print(full_name_with_name(dummy.One.Two)) # Wrong dummy.Two >>> print(full_name_with_qualname(dummy.One)) # Correct dummy.One >>> print(full_name_with_qualname(dummy.One.Two)) # Correct dummy.One.Two

Tenga en cuenta que también funciona correctamente para buildins:

>>> print(full_name_with_qualname(print)) builtins.print >>> import builtins >>> builtins.print <built-in function print>


Aquí hay uno basado en la excelente respuesta de Greg Bacon, pero con un par de controles adicionales:

__module__ puede ser None (de acuerdo con los documentos), y también para un tipo como str puede ser __builtin__ (que es posible que no desee que aparezca en los registros o lo que sea). Lo siguiente verifica ambas posibilidades:

def fullname(o): module = o.__class__.__module__ if module is None or module == str.__class__.__module__: return o.__class__.__name__ return module + ''.'' + o.__class__.__name__

(Puede haber una forma mejor de verificar __builtin__ . Lo anterior simplemente se basa en el hecho de que str está siempre disponible, y su módulo siempre es __builtin__ )


Con el siguiente programa

#! /usr/bin/env python import foo def fullname(o): return o.__module__ + "." + o.__class__.__name__ bar = foo.Bar() print fullname(bar)

y Bar definido como

class Bar(object): def __init__(self, v=42): self.val = v

la salida es

$ ./prog.py foo.Bar


Considere usar el módulo de inspect que tiene funciones como getmodule que podría ser lo que está buscando:

>>>import inspect >>>import xml.etree.ElementTree >>>et = xml.etree.ElementTree.ElementTree() >>>inspect.getmodule(et) <module ''xml.etree.ElementTree'' from ''D:/tools/python2.5.2/lib/xml/etree/ElementTree.pyc''>


Dado que el interés de este tema es obtener nombres completamente calificados, aquí hay una trampa que se produce al usar importaciones relativas junto con el módulo principal existente en el mismo paquete. P.ej:

$ mkdir -p /tmp/fqname/foo $ touch /tmp/fqname/foo/__init__.py $ cat<<END > /tmp/fqname/foo/bar.py > from baz import Baz > print Baz.__module__ > END $ cat<<END > /tmp/fqname/foo/baz.py > class Baz: pass > END $ cat <<END > /tmp/fqname/main.py > import foo.bar > from foo.baz import Baz > print Baz.__module__ > END $ cat <<END > /tmp/fqname/foo/hum.py > import bar > import foo.bar > END $ PYTHONPATH=/tmp/fqname python /tmp/fqname/main.py foo.baz foo.baz $ PYTHONPATH=/tmp/fqname python /tmp/fqname/foo/bar.py baz $ PYTHONPATH=/tmp/fqname python /tmp/fqname/foo/hum.py baz foo.baz

Cuando la barra de importación de zumbidos usa la ruta relativa, la barra ve Baz.__module__ como simplemente "baz", pero en la segunda importación que usa nombre completo, bar ve lo mismo que "foo.baz".

Si persiste en nombres completos en alguna parte, es mejor evitar importaciones relativas para esas clases.


Este es un truco pero estoy soportando 2.6 y solo necesito algo simple:

>>> from logging.handlers import MemoryHandler as MH >>> str(MH).split("''")[1] ''logging.handlers.MemoryHandler''


Las respuestas proporcionadas no tratan con clases anidadas. Aunque no está disponible hasta Python 3.3 ( PEP 3155 ), realmente quieres usar __qualname__ de la clase. Eventualmente (3.4? PEP 395 ), __qualname__ también existirá para que los módulos se ocupen de los casos donde se cambia el nombre del módulo (es decir, cuando se renombra a __main__ ).


Ninguna de las respuestas aquí funcionó para mí. En mi caso, estaba usando Python 2.7 y sabía que solo estaría trabajando con las clases de object newstyle.

def get_qualified_python_name_from_class(model): c = model.__class__.__mro__[0] name = c.__module__ + "." + c.__name__ return name


__module__ haría el truco.

Tratar:

>>> import re >>> print re.compile.__module__ re

Este sitio sugiere que __package__ podría funcionar para Python 3.0; Sin embargo, los ejemplos dados allí no funcionarán en mi consola Python 2.5.2.