Вы должны полностью квалифицировать свой импорт, то есть вместо:
from file2 import class2
использовать
from .file2 import class2
заметить .
после from
.
Обновление: проверка:
(dev) go|c:\srv\tmp\unttst\project> tree
.
|-- src
| |-- __init__.py
| |-- file1.py
| `-- file2.py
`-- test
|-- __init__.py
`-- test1.py
2 directories, 5 files
(dev) go|c:\srv\tmp\unttst\project> type src\file1.py
from .file2 import Class2
class class1:
pass
(dev) go|c:\srv\tmp\unttst\project> type src\file2.py
class Class2:
pass
(dev) go|c:\srv\tmp\unttst\project> type test\test1.py
from src.file1 import class1
(dev) go|c:\srv\tmp\unttst\project> python -m unittest discover
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
(dev) go|c:\srv\tmp\unttst\project>
Обратите внимание, что я запускаю команду из каталога, где from src.xxx
имеет смысл.
Обновление 2: Примечание: Python не предназначен для непосредственного запуска отдельных файлов в подкаталоге (то есть в качестве точки входа).Гвидо категорически против такого использования, поэтому вряд ли это изменится.Несмотря на то, что вы можете обойти это, сделать это правильно очень просто и стоит учиться.
Давайте сначала изменим src/file1.py
на функцию main()
:
(dev) go|c:\srv\tmp\unttst\project> cat src\file1.py
from .file2 import Class2
class class1:
pass
def main():
print("hello from main")
Примечание: я не добавляю секцию if __name__=="__main__"
.
Правильный способ вызова этой функции из командной строки - сделать project
"настоящим" пакетом.
A "настоящий "пакет создается путем добавления файла setup.py
.Файлы setup.py
могут содержать много полей, но для этого варианта использования необходимы только следующие:
(dev) go|c:\srv\tmp\unttst\project> cat setup.py
from setuptools import setup
setup(
name="myproject",
entry_points={
'console_scripts': """
run-file1 = src.file1:main
"""
}
)
обратите внимание, что setup.py
находится в папке project
.
Далее вы устанавливаете пакет в режиме «разработки»:
(dev) go|c:\srv\tmp\unttst\project> pip install -e .
замечают .
в конце.
entry_points .. console_scripts в файле setup.py
имееттеперь создал новую команду оболочки для вас:
(dev) go|c:\srv\tmp\unttst\project> run-file1
hello from main
строка console_scripts
run-file1 = src.file1:main
говорит о создании команды оболочки с именем run-file
, которая должна выполнить функцию main
, найденную вsrc.file1
.