2010-01-07 14 views

Respuesta

88

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 define como

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

la salida es

+2

+1 ¡Bonito! ¿Por qué no agregas '__package__'? –

+2

Esto parece devolver el módulo donde se definió la barra, no donde se definió la barra. Si el propósito del registro es saber exactamente qué tipo de objeto era, entonces esto no parece ayudar. –

+15

Debe ser 'o .__ class __.__ module__', creo ... –

7

__module__ harían el truco.

Probar:

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

This site 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.

+5

Eso hace el truco, gracias! Para el nombre completamente calificado usaré '"% s.% S "% (x .__ clase __.__ módulo__, x .__ clase __.__ nombre __)' –

19

Considere el uso del módulo inspect que tiene funciones como getmodule que podría ser lo que buscas:

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

Dado que el interés de este tema es obtener nombres totalmente calificados, aquí hay una trampa que se produce cuando se utilizan importaciones relativas junto con el módulo principal existente en el mismo paquete. 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 las importaciones de barras usando hum ruta relativa, bar Baz.__module__ ve simplemente como "Baz", pero en la segunda importación que utiliza el nombre completo, la barra ve lo mismo que "foo.baz".

Si persiste el nombre completo en alguna parte, es mejor evitar las importaciones relativas para esas clases.

10

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

__module__ puede haber None (de acuerdo con los documentos), y también para un tipo como str Puede ser __builtin__ (que se podría no querer aparecer en los registros o lo que sea). Las siguientes comprobaciones para 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 mejor manera de comprobar si hay __builtin__ Lo anterior simplemente se basa en el hecho de que str siempre está disponible, y su módulo es siempre __builtin__.)

17

Las respuestas proporcionadas no tratan con clases anidadas. Aunque no está disponible hasta Python 3.3 (PEP 3155), realmente desea utilizar __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__).

+3

Si usa https: // github. com/wbolster/qualname puede obtener un equivalente de __qualname__ en versiones anteriores. –

+0

I.e. 'Escriba .__ module__ + '.' + Escriba .__ qualname__'. – Kentzo

3

Esto es un truco pero apoyo 2.6 y simplemente necesita algo simple:

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

'logging.handlers.MemoryHandler' 
0

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 newstyle object clases.

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