【问题标题】:Python project structure - Avoid setting directory in all filesPython 项目结构 - 避免在所有文件中设置目录
【发布时间】:2022-12-06 13:22:02
【问题描述】:

我有一个名为我的项目. 它包含以下内容:

  1. __init__.py(空,即没有代码)
  2. main.py(用于运行“我的最终项目”)
  3. 名为data 的文件夹,目前仅包含data.sqlite
  4. 一个名为utils 的 foller,它有一个 __init__.py 和一些其他的 .py 文件,例如 data_handler.py
  5. 其他一些与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:\Users\my_pcs_username\anaconda3\envs\MyProject\python.exe C:/Users/my_pcs_username/Desktop/MyProject/utils/data_handler.py

    制作这样一个每个文件都可以作为自己的模块运行的项目的正确方法是什么?

【问题讨论】:

    标签: python path virtualenv structure project


    【解决方案1】:

    这只是回答如何在没有 chdir 的情况下查找非 Python 文件等 *


    这个怎么样?

    基本上,将 pathlib.Path 与始终存在的 __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
    

    * 如何制作可独立运行的脚本不一定非常复杂,但假设人们甚至同意这是一个好主意,可能有多种方法可以做到这一点。

    我使用 click 并为有理由单独运行的 Python 文件添加看起来像这样的代码。

    这可能是一个相当开放的解释:我的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()
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-29
      • 2013-04-13
      相关资源
      最近更新 更多