Как вы отображаете полное имя класса на его объект класса в Python? - PullRequest
9 голосов
/ 28 августа 2011

Вы можете получить полное имя класса объекта Python, как это (см. этот вопрос ):

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

Как сделать обратное, то есть сопоставить полное имя класса, например 'Queue.PriorityQueue', с соответствующим объектом класса (Queue.PriorityQueue)?

Ответы [ 3 ]

11 голосов
/ 28 августа 2011

Вы можете использовать importlib в 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()
1 голос
/ 28 августа 2011

Для 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

0 голосов
/ 28 августа 2011

Идентификаторы в 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__.

...