Я пытаюсь динамически импортировать модули Python, которые соответствуют шаблону во время выполнения. Модули расположены внутри пакета Python.Проблемы с pkgutil.iter_modules() в Windows
Функция я использую, чтобы найти модули является:
def load_modules_from_dir(dirname, pattern=""):
modules = []
for importer, package_name, _ in pkgutil.iter_modules([dirname]):
if re.search(pattern, package_name):
full_package_name = '%s.%s' % (dirname, package_name)
if full_package_name not in sys.modules:
module = importer.find_module(package_name).load_module(full_package_name)
modules.append(module)
return modules
Я называю это следующим образом:
module_dir = os.path.join(os.path.dirname(__file__))
modules = utils.load_modules_from_dir(module_dir, "jscal$")
В Linux находит все модули, но на Windows, он не находит ни одного модулей вообще. Если я напечатаю dirname
в функции load_modules_from_dir
, я получаю: H:\temp\linx\dist\calibrate\dcljscal
Я воспроизвел его в оболочке Python на Windows и прибил его к разделителю пути. Следующие ничего не находит:
>>> for x in pkgutil.iter_modules(['H:\temp\linx\dist\calibrate\dcljscal']):print x
...
>>>
Если я заменить разделитель пути для Windows с Linux один, он работает:
>>> for x in pkgutil.iter_modules(['H:/temp/linx/dist/calibrate/dcljscal']):print x
...
(<pkgutil.ImpImporter instance at 0x00AD9C60>, 'demojscal', True)
(<pkgutil.ImpImporter instance at 0x00AD9C60>, 'dx2cremjscal', True)
(<pkgutil.ImpImporter instance at 0x00AD9C60>, 'linxjscal', True)
>>>
Это также работает, если я заменю \
с \\
, в основном спасаясь разделитель пути для Windows :
>>> for x in pkgutil.iter_modules(['H:\\temp\\linx\\dist\\calibrate\\dcljscal']):print x
...
(<pkgutil.ImpImporter instance at 0x00AD9E68>, 'demojscal', True)
(<pkgutil.ImpImporter instance at 0x00AD9E68>, 'dx2cremjscal', True)
(<pkgutil.ImpImporter instance at 0x00AD9E68>, 'linxjscal', True)
>>>
кажется, что путь, порожденный os.path.join(os.path.dirname(__file__))
не является портативным.
Я бы ожидал, что os.path.join()
дал бы мне правильный путь, который я могу использовать без изменений в pkgutil.iter_modules()
. Что я здесь делаю неправильно?
Я использую Python 2.7.11 для Windows XP.
Не смотря на '' \ t'', вы не поднимаете никаких тревог для вас? – eryksun
@eryksun Да, вы правы.Если я заменю '\ t' на' \\ t', он также будет работать в оболочке Python. Но вы заставили меня задуматься. Путь, возвращаемый 'os.path.join()', должен уже содержать экранированную версию пути. Когда я печатаю параметр 'dirname' в функции' load_modules_from_dir', я получаю: 'H: \ temp \ linx \ dist \ calibrate \ dcljscal', а не' H: emp \ linx \ dist \ calibrate \ dcljscal'. Теперь вопрос в том, почему он не работает в 'pkgutil.iter_modules()'? – NZD
'os.path.join (os.path.dirname (__ file __))' не имеет смысла. Используйте 'os.path.abspath (os.path.dirname (__ file __))'. – eryksun