Модуль чтения Pyclbr завершается ошибкой при запуске в сценарии для другого каталога - PullRequest
2 голосов
/ 14 октября 2019

Я хочу запустить функцию readmodule из pyclbr. Код Python отлично работает в терминале, но не работает в скрипте при вызове из терминала. Это связано с изменением каталога.

Я пытался прочитать исходный код, но не смог определить отличительные черты.

Это код в сценарии:

import os
import pyclbr
import sys

print(os.getcwd())
os.chdir('rto')
print(os.getcwd())
source_code = pyclbr.readmodule('car')
print(source_code)
source_code = pyclbr.readmodule('transport')
print(source_code)
source_code = pyclbr.readmodule('vehicles')
print(source_code)

Я запускаю приведенный выше скрипт с этой командой: /usr/local/bin/python3 test_readmodule.py и сталкиваюсь со следующей ошибкой:

/Users/aviralsrivastava/dev/generate_uml/inheritance_and_dependencies
/Users/aviralsrivastava/dev/generate_uml/inheritance_and_dependencies/rto
Inside _readmodule, module=car, path=[]
Traceback (most recent call last):
  File "test_readmodule.py", line 8, in <module>
    source_code = pyclbr.readmodule('car')
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/pyclbr.py", line 123, in readmodule
    for key, value in _readmodule(module, path or []).items():
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/pyclbr.py", line 190, in _readmodule
    if spec.submodule_search_locations is not None:
AttributeError: 'NoneType' object has no attribute 'submodule_search_locations'

Однако, когда я запускаю тот же код в оболочке Python3, в том же каталоге, где я находилсяВыполнение команды python3 для сценария:

➜  inheritance_and_dependencies git:(master) ✗ /usr/local/bin/python3
Python 3.7.4 (default, Sep  7 2019, 18:27:02)
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import pyclbr
>>> import sys
>>>
>>> print(os.getcwd())
/Users/aviralsrivastava/dev/generate_uml/inheritance_and_dependencies
>>> os.chdir('rto')
>>> print(os.getcwd())
/Users/aviralsrivastava/dev/generate_uml/inheritance_and_dependencies/rto
>>> source_code = pyclbr.readmodule('car')
Inside _readmodule, module=car, path=[]
Inside _readmodule, module=vehicles, path=[]
Inside _readmodule, module=transport, path=[]
Inside _readmodule, module=vehicles, path=[]
returning from 157
>>> print(source_code)
{'Vehicle': <pyclbr.Class object at 0x105369510>, 'Farzi': <pyclbr.Class object at 0x1053c5e50>, 'CarPollutionPermit': <pyclbr.Class object at 0x1053c58d0>, 'BikePollutionPermit': <pyclbr.Class object at 0x1053c5e10>, 'Car': <pyclbr.Class object at 0x1052ebd50>, 'Bike': <pyclbr.Class object at 0x1053df210>}
>>> source_code = pyclbr.readmodule('transport')
Inside _readmodule, module=transport, path=[]
returning from 157
>>> print(source_code)
{'Vehicle': <pyclbr.Class object at 0x105369510>, 'Farzi': <pyclbr.Class object at 0x1053c5e50>, 'CarPollutionPermit': <pyclbr.Class object at 0x1053c58d0>, 'BikePollutionPermit': <pyclbr.Class object at 0x1053c5e10>}
>>> source_code = pyclbr.readmodule('vehicles')
Inside _readmodule, module=vehicles, path=[]
returning from 157
>>> print(source_code)
{'Vehicle': <pyclbr.Class object at 0x105369510>, 'Farzi': <pyclbr.Class object at 0x1053c5e50>}

Я в порядке с ошибкой, но не в порядке с различным поведением в оболочке и сценарии.

1 Ответ

1 голос
/ 14 октября 2019

pyclbr.readmodule ищет модули в обычном пути поиска модулей sys.path, который может быть дополнен дополнительными каталогами, заданными аргументом path.

Когда вы запускаете python для запуска интерактивного сеанса,один из элементов sys.path - это '.', относительный путь, относящийся к текущему каталогу, каким бы ни был текущий каталог в данный момент. Таким образом, изменение текущего каталога с помощью os.chdir влияет на поиск модуля.

Когда вы запускаете скрипт, в зависимости от того, как вы его запускаете, вместо записи '.' может использоваться другой путь, или это может бытьушел без замены. В этом случае изменение текущего каталога не повлияет на поиск модуля или повлияет на него более странным образом.


Вместо изменения рабочего каталога вы должны либо передать аргумент path в pyclbr.readmodule:

pyclbr.readmodule('car',  path=['rto'])

или, если rto предполагается как пакет и car подмодуль пакета, передайте 'rto.car' в качестве имени модуля вместо car:

pyclbr.readmodule('rto.car')
...