我有一个Python项目叫做MyProject.它包含以下内容:
__init__.py
(空,即无代码)main.py
(用于运行"我的期末项目")- 一个名为
data
的文件夹,目前只包含data.sqlite
- 一个名为
utils
的追随者,它有一个__init__.py
和一些其他的。py文件,例如data_handler.py
。 - 与
utils
结构相同的其他文件夹。
在我的.py文件中,例如data_handler.py
,我包含了通常的
if __name__ == "__main__":
以便将文件作为单个模块运行,而不执行main.py
中的所有内容。
由于许多文件需要使用来自data.sqlite
的数据,我使用相对路径来找到它。但是,目前我以
if __name__ == "__main__":
os.chdir('C:\Users\my_pcs_username\Desktop\MyProject\')
# code to be executed in this file
这似乎不是处理多个文件的正确方式,但如果我不包括目录的更改,代码将无法工作。当我在PyCharm中运行任何文件时,终端用以下行初始化:C:Usersmy_pcs_usernameanaconda3envsMyProjectpython.exe C:/Users/my_pcs_username/Desktop/MyProject/utils/data_handler.py
什么是正确的方式,使这样的项目,每个文件都可以作为自己的模块运行?
这只是回答如何找到没有chdir和*
之类的非python文件。
这个怎么样?
基本上,使用pathlib。路径与__file__
变量一起,该变量始终存在(在Python代码不存储在文件系统中的特殊环境中可能不存在),并对应于您的Python源文件。
from pathlib import Path
PA_SCRIPT = Path(__file__)
def main():
sqldata = PA_SCRIPT.parent / "data" / "data.sqlite"
data = sqldata.read_text()
print(f"main:{data}")
if __name__ == "__main__":
main()
文件.
├── __init__.py
├── data
│ └── data.sqlite
└── main.py
% cat data/data.sqlite
I am your db
程序输出:
% py main.py
main: I am your db
*
如何制作可独立运行的脚本并不一定非常复杂,但假设人们甚至同意这是一个好主意,可能有多种方法可以做到这一点。
对于有理由单独运行的Python文件,我使用像这样的click和sprinkle代码。
这可以是一个相当开放的解释:我的constants.py
文件可以单独运行,它基本上很好地打印了它的globals()
。这听起来很奇怪,除了许多值来自环境变量,所以在源代码中不可见。
关于数据文件,您将使用相同的机制,但只需考虑python脚本与data
目录的相对位置。所以sqldata = PA_SCRIPT.parent.parent / "data" / "data.sqlite"
(我认为)。
import click
# notice how this is imported all the way from the top?
# relative imports always give me a hard time.
from MyProject.utils.data_handler import Foo
# or to load the whole module
import MyProject.utils.data_handler as data_handler
@click.command()
def main():
...
if __name__ == "__main__":
main()