2011-08-28 56 views
8

你可以得到一個Python對象這樣的完全限定類名(見this question):如何在Python中將完全限定的類名映射到其類對象?

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

你怎麼做的倒數,即像'Queue.PriorityQueue'映射一個完全合格的類名與其關聯的類對象(Queue.PriorityQueue)?

+0

我不認爲你可以做,因爲如果我'從隊列導入PriorityQueue'然後'Queue.PriorityQueue'不是我的程序中的類對象,它只是'PriorityQueue'。 – agf

+0

長文本,但我認爲這就是你需要:[鏈接](http://blog.garlicsim.org/post/2958629526/address-tools-more-powerful-replacements-for-eval) – JBernardo

回答

10

可以在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() 

在舊版本中您可以使用__import__功能。它默認返回包導入的頂層(例如xml)。然而,如果你傳遞一個非空fromlist,它返回指定的模塊來代替:

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

感謝@eryksun,這正是我們所需要的(我們使用Python 2.6)。 –

0

Python中的標識符並非真的是這樣使用的,但是sys.modules__import__可以實現您想要的功能。

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 
實施例使用
my_queue = get_by_qualified_name("Queue.Queue")() 
my_queue.put("Hello World") 
print my_queue.get() # prints "Hello World" 

如果模塊是在不將其導入作爲__ALL__一部分的包這將失敗。這是可以解決的,但它需要更詳細地使用__import__

+0

這也將失敗if你的字符串不代表'module.attr1.attr2',而是'package1.package2.module.attr1.attr2'。 – glglgl

1

對於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 

相關問題