Отражение в Python намного легче и намного более гибко, чем это находится в Java.
я рекомендую читать этот учебное руководство
, Там не прямая функция (что я знаю о), который берет полностью определенное имя класса и возвращает класс, однако у Вас есть все части, должен был создать это, и можно соединить их вместе.
Один совет, хотя: не пытайтесь программировать в стиле Java, когда Вы будете в Python.
, Если можно объяснить, что является им, что Вы пытаетесь сделать, возможно, мы можем помочь Вам найти больше pythonic способа сделать его.
Вот функция, которая делает то, что Вы хотите:
def get_class( kls ):
parts = kls.split('.')
module = ".".join(parts[:-1])
m = __import__( module )
for comp in parts[1:]:
m = getattr(m, comp)
return m
можно использовать возвращаемое значение этой функции, как будто это был сам класс.
Вот пример использования:
>>> D = get_class("datetime.datetime")
>>> D
<type 'datetime.datetime'>
>>> D.now()
datetime.datetime(2009, 1, 17, 2, 15, 58, 883000)
>>> a = D( 2010, 4, 22 )
>>> a
datetime.datetime(2010, 4, 22, 0, 0)
>>>
, Как это работает?
Мы используем __import__
для импорта модуля, который содержит класс, который потребовал, чтобы мы сначала извлекли имя модуля из полностью определенного имени. Тогда мы импортируем модуль:
m = __import__( module )
В этом случае, m
будет только относиться к высокоуровневому модулю,
, Например, если Ваши жизни класса в foo.baz
модуль, то m
будет модуль foo
, Мы можем легко получить ссылку на [1 111], использование getattr( m, 'baz' )
, Чтобы добраться от высокоуровневого модуля до класса, иметь для рекурсивного использования gettatr
на частях имени класса
Говорят, например, если Вы, которые имя класса foo.baz.bar.Model
тогда, мы делаем это:
m = __import__( "foo.baz.bar" ) #m is package foo
m = getattr( m, "baz" ) #m is package baz
m = getattr( m, "bar" ) #m is module bar
m = getattr( m, "Model" ) #m is class Model
Это - то, что происходит в этом цикле:
for comp in parts[1:]:
m = getattr(m, comp)
В конце цикла, m
будет ссылка на класс. Это означает, что m
на самом деле сам класс, можно сделать, например:
a = m() #instantiate a new instance of the class
b = m( arg1, arg2 ) # pass arguments to the constructor
Принятие класса находится в Вашем объеме:
globals()['classname'](args, to, constructor)
Иначе:
getattr(someModule, 'classname')(args, to, constructor)
Редактирование: Отметьте, Вы не можете дать имя как 'foo.bar' к getattr. Необходимо будет разделить его. и назовите getattr () на каждой части слева направо. Это обработает это:
module, rest = 'foo.bar.baz'.split('.', 1)
fooBar = reduce(lambda a, b: getattr(a, b), rest.split('.'), globals()[module])
someVar = fooBar(args, to, constructor)
Кажется приближением к этому с середины вместо начала. Что Вы действительно пытаетесь сделать? Нахождение класса, связанного с данной строкой, является средством для конца.
при разъяснении проблемы которая могла бы потребовать собственного умственного рефакторинга, лучшее решение может представить себя.
, Например: Вы пытаетесь загрузить сохраненное основанное на объектах на его имени типа и ряде параметров? Python записывает это несоление, и необходимо посмотреть модуль рассола . И даже при том, что процесс несоления делает точно, что Вы описываете, Вы не должны волноваться о том, как он работает внутренне:
>>> class A(object):
... def __init__(self, v):
... self.v = v
... def __reduce__(self):
... return (self.__class__, (self.v,))
>>> a = A("example")
>>> import pickle
>>> b = pickle.loads(pickle.dumps(a))
>>> a.v, b.v
('example', 'example')
>>> a is b
False
Я должен был получить объекты для всех существующих классов в my_package
. Таким образом, я импортирую все необходимые классы в my_package
__init__.py
.
, Таким образом, моя структура каталогов похожа на это:
/my_package
- __init__.py
- module1.py
- module2.py
- module3.py
И мой __init__.py
похож на это:
from .module1 import ClassA
from .module2 import ClassB
Затем я создаю функцию как это:
def get_classes_from_module_name(module_name):
return [_cls() for _, _cls in inspect.getmembers(__import__(module_name), inspect.isclass)]
, Где module_name = 'my_package'
осматривают документ: https://docs.python.org/3/library/inspect.html#inspect.getmembers
Еще одна реализация.
def import_class(class_string):
"""Returns class object specified by a string.
Args:
class_string: The string representing a class.
Raises:
ValueError if module part of the class is not specified.
"""
module_name, _, class_name = class_string.rpartition('.')
if module_name == '':
raise ValueError('Class name must contain module part.')
return getattr(
__import__(module_name, globals(), locals(), [class_name], -1),
class_name)