2011-08-28 4 views
8

È possibile ottenere il nome completo della classe di un oggetto Python come questo (vedi this question):Come si esegue il mapping di un nome classe completo al relativo oggetto di classe in Python?

>>> import Queue 
>>> q = Queue.PriorityQueue() 
>>> def fullname(o): 
    return o.__module__ + "." + o.__class__.__name__ 
... 
>>> fullname(q) 
'Queue.PriorityQueue' 
>>> 

Come si fa a fare l'inverso, vale a dire, la mappa di un nome di classe completo come 'Queue.PriorityQueue' al suo oggetto classe associata (Queue.PriorityQueue)?

+0

io non credo che si può, perché se io 'da Queue import PriorityQueue' quindi' Queue.PriorityQueue' non è un oggetto di classe nel mio programma, è solo 'PriorityQueue'. – agf

+0

Un lungo testo ma penso che sia quello che ti serve: [Link] (http://blog.garlicsim.org/post/2958629526/address-tools-more-powerful-replacements-for-eval) – JBernardo

risposta

10

È possibile utilizzare importlib in 2.7:

from importlib import import_module 

name = 'xml.etree.ElementTree.ElementTree' 
parts = name.rsplit('.', 1) 
ElementTree = getattr(import_module(parts[0]), parts[1]) 
tree = ElementTree() 

Nelle versioni più vecchie è possibile utilizzare la funzione di __import__. Per impostazione predefinita, restituisce il livello principale dell'importazione di un pacchetto (ad esempio xml). Tuttavia, se si passa un non vuoto fromlist, restituisce il modulo chiamato invece:

name = 'xml.etree.ElementTree.ElementTree' 
parts = name.rsplit('.', 1)  
ElementTree = getattr(__import__(parts[0], fromlist=['']), parts[1]) 
tree = ElementTree() 
+0

Grazie a @eryksun, questo è esattamente ciò di cui avevamo bisogno (stiamo usando Python 2.6). –

0

Gli identificatori in Python non sono pensati per essere usati in questo modo, ma con sys.modules e __import__ si può ottenere ciò che si desidera.

import sys 

def get_by_qualified_name(name): 
    parts = name.split(".") 
    module_name = parts[0] 
    attribute_names = parts[1:] 

    if module_name not in sys.modules: 
     __import__(module_name) 

    result = sys.modules[module_name] 

    for attribute_name in attribute_names: 
     result = getattr(result, attribute_name) 

    return result 
Esempio Utilizzare
my_queue = get_by_qualified_name("Queue.Queue")() 
my_queue.put("Hello World") 
print my_queue.get() # prints "Hello World" 

Ciò sicuro se il modulo è in un pacchetto che non importa come parte di __ALL__. Questo è possibile risolvere, ma richiede un uso più elaborato di __import__.

+0

Questo fallirà anche se la tua stringa non significa 'module.attr1.attr2', ma' package1.package2.module.attr1.attr2'. – glglgl

1

Per Python 2,6/2,7



    import sys 
    def hasModule(moduleName): 
     return moduleName in sys.modules 

    def getModule(moduleName): 
     if hasModule(moduleName): 
      return sys.modules[moduleName] 

    def loadModule(moduleName): 
     if not hasModule(moduleName): 
      return __import__(moduleName) 
     return getModule(moduleName) 

    def createInstance(fqcn, *args): 
     paths = fqcn.split('.') 
     moduleName = '.'.join(paths[:-1]) 
     className = paths[-1] 
     module = loadModule(moduleName) 
     if module is not None: 
      return getattr(module, className)(*args) 

    pq = "Queue.PriorityQueue" 
    pqObj = createInstance(pq) 
    pqObj.put(1) 
    print pqObj.get() #1