如何将完全限定的类名映射到 Python 中的类对象?
Posted
技术标签:
【中文标题】如何将完全限定的类名映射到 Python 中的类对象?【英文标题】:How do you map a fully qualified class name to its class object in Python? 【发布时间】:2011-11-05 08:10:19 【问题描述】:您可以像这样获取 Python 对象的完全限定类名(请参阅this question):
>>> import Queue
>>> q = Queue.PriorityQueue()
>>> def fullname(o):
return o.__module__ + "." + o.__class__.__name__
...
>>> fullname(q)
'Queue.PriorityQueue'
>>>
你如何做相反的事情,即将一个完全限定的类名,如'Queue.PriorityQueue'
映射到它的关联类对象(Queue.PriorityQueue
)?
【问题讨论】:
我不认为你可以,因为如果我from Queue import PriorityQueue
那么Queue.PriorityQueue
在我的程序中不是一个类对象,它只是PriorityQueue
。
很长的文字,但我认为这就是您需要的:Link
【参考方案1】:
您可以在 2.7 中使用 importlib:
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()
【讨论】:
感谢@eryksun,这正是我们所需要的(我们使用的是 Python 2.6)。【参考方案2】:对于 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
【讨论】:
【参考方案3】: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__
。
【讨论】:
如果你的字符串不是module.attr1.attr2
,而是package1.package2.module.attr1.attr2
,这也会失败。以上是关于如何将完全限定的类名映射到 Python 中的类对象?的主要内容,如果未能解决你的问题,请参考以下文章