首页 > 编程问答 >Python:添加到相对于当前运行脚本的 sys.path 的最佳方法

Python:添加到相对于当前运行脚本的 sys.path 的最佳方法

时间:2024-07-30 15:13:11浏览次数:7  
标签:python python-import

我有一个充满脚本的目录(比如说 project/bin )。我还有一个位于 project/lib 的库,并希望脚本自动加载它。这是我通常在每个脚本的顶部使用的:

#!/usr/bin/python
from os.path import dirname, realpath, sep, pardir
import sys
sys.path.append(dirname(realpath(__file__)) + sep + pardir + sep + "lib")

# ... now the real code
import mylib

这有点麻烦、丑陋,并且必须粘贴在每个文件的开头。有没有更好的方法来做到这一点?

我真正希望的是像这样顺利的东西:

#!/usr/bin/python
import sys.path
from os.path import pardir, sep
sys.path.append_relative(pardir + sep + "lib")

import mylib

或者甚至更好,当我的编辑器(或具有提交访问权限的其他人) ) 决定重新排序导入作为其清理过程的一部分:

#!/usr/bin/python --relpath_append ../lib
import mylib

这不会直接移植到非 posix 平台,但它会保持干净。


有几种方法可以实现这一点,而不必在每个脚本中都写出路径操作:

1. 使用相对导入(仅限于包)

如果你打算将 project 构建成一个包,那么这是最干净和 Pythonic 的方法。

  • project 目录结构组织为包: project/ __init__.py bin/ script1.py script2.py lib/ __init__.py mylib.py

  • script1.py script2.py 中,使用相对导入:

    ```python from ..lib import mylib

    # ... 现在是真正的代码 mylib.some_function() ```

  • 通过运行 pip install -e . (在 project 目录中)将 project 安装为可编辑包。这会将 project 放入 sys.path 中。

这种方法的优点是代码更易读,并且鼓励良好的项目结构。但是,它要求你将 project 构建为一个包。

2. 使用 PYTHONPATH 环境变量

你可以设置 PYTHONPATH 环境变量来包含 project/lib 目录。

  • 在你的 shell 中(或者在激活虚拟环境的脚本中):

    bash export PYTHONPATH=$PYTHONPATH:/path/to/your/project/lib

  • 现在你可以在你的脚本中直接导入 mylib

    python import mylib

这种方法的优点是简单,并且不需要修改你的脚本。缺点是它依赖于环境变量,这在某些情况下可能不方便。

3. 使用 .pth 文件

你可以创建一个 .pth 文件,其中包含要添加到 sys.path 的路径。

  • 在你的 Python 安装的 site-packages 目录中创建一个名为 myproject.pth 的文件(使用 python -m site --user-site 找到该目录)。

  • myproject.pth 文件中,添加一行:

    /path/to/your/project/lib

  • 现在你可以在你的脚本中直接导入 mylib

这种方法的优点是一劳永逸,不需要修改你的脚本或设置环境变量。缺点是它会影响所有使用该 Python 安装的项目。

4. 使用 sitecustomize 模块

你可以创建一个 sitecustomize.py 模块来自定义 Python 启动行为。

  • 在你的 Python 安装的 site-packages 目录中创建一个名为 sitecustomize.py 的文件。

  • sitecustomize.py 文件中,添加以下代码:

    python import sys sys.path.append('/path/to/your/project/lib')

  • 现在你可以在你的脚本中直接导入 mylib

这种方法与使用 .pth 文件类似,但它为你提供了更大的灵活性,可以执行更复杂的初始化。

关于 sys.path.append_relative 的想法

虽然 sys.path.append_relative 看起来像一个好主意,但它在 Python 中并不存在。这是因为 sys.path 中的路径应该始终是绝对路径。使用相对路径可能会导致问题,尤其是在使用不同的工作目录运行脚本时。

建议

对于你的情况,我建议使用 相对导入 (如果你打算将 project 构建为一个包)或者 PYTHONPATH 环境变量 。这两种方法都是简单、直接且易于维护的。

标签:python,python-import
From: 8663076

相关文章

  • python身份证号码+姓名一致性核验、身份证号码真伪查询API集成
    身份证号码+姓名核验的方式,顾名思义是身份证二要素核验,一般情况下,身份证真伪查询需要上公安户籍系统查询,但此种方式仅适合个人查询,企业要想随时随地实现身份证实名认证的功能,便需要集成身份证实名认证接口功能。翔云人工智能开放平台提供身份证号实名认证接口,实时联网,上传身份证......
  • 如何将数字分配给返回的 python 数据列表,我可以调用这些数据来打印
    这里完全是菜鸟。我在网上搜索过,找不到我想要做的事情的答案。我的代码在这里:importbs4asbsimporturllib.requestsauce=urllib.request.urlopen('https://www.amazon.com/gp/rss/bestsellers/kitchen/289851/ref=zg_bs_289851_rsslink').read()soup=bs.Beautiful......
  • python API增值税发票四要素核验、数电票查验、医疗票查验
    长期以来,对发票进行高效的管理一直困扰着众多企业财务,手动录入效率慢、出错率高、纸质发票易丢失等。今天,翔云为广大企业提供了发票查验接口与财政票据查验接口服务,可针对增值税发票管理系统开具发票,医疗票据、非税收入等财政类票据进行真伪查验。翔云发票识别接口,使得企业财务无......
  • 如何使用 python 在 influxdb 中创建组织和存储桶
    如何使用python在influxdb中创建组织和存储桶?我有一个python脚本,用于在influxdb中创建组织和存储桶,但它无法工作并返回未经授权的响应任何人可以使用influxdbapi帮助我解决这个问题吗?HTTPresponsebody:{"code":"unauthorized","message":"write:org......
  • Python - File opening modes and buffering
    'r'-readmode(default)'w'-writemode'a'-appendmode'x'-exclusivecreationWeknowthatthemode'r'opensanexistingfileforreadingonly;thefileshouldalreadyexist.Ifyouopenafilein......
  • 如何使用 Python 对图像中的掩模部分进行聚类?
    我需要以这样的方式拆分蒙版:如果蒙版内存在不一致,则会将其分开。例如,如果我在一只猫上画一个面具,我希望宽的部分(身体)是一个面具,窄的部分(尾巴)是另一个面具。目前,我有一个连续的面具,其中包括两者猫的身体和尾巴。我想将其分成两个不同的面具。如何使用Python实现此目的?原......
  • 如何在 python 中为具有不同类型作为值的字典添加类型声明
    我有一个字典如下my_dict={"key_1":"value_1","key_2":{"key_1":True,"key_2":1200}"key_3":True,}并且在我的类中@dataclassclassTestClass:my_dict:typing......
  • Python TypedDict:继承另一个TypedDict时的函数语法
    给定这种类型:classTPerson(TypedDict):name:straddress:str我想要另一个TypedDict继承前一个,例如:classTDealer(TPerson):db-id:intpolice_record:strarrested_now:boolclassTConsumer(TPerson):db-id:intpreferred_product:......
  • 如何让 python 类型在需要父类时将子类识别为有效类型?
    这是我需要做的一个最小示例:fromtypingimportCallable,AnyclassData:passclassSpecificData(Data):passclassEvent:passclassSpecificEvent(Event):passdefdetect_specific_event(data:SpecificData,other_info:str)->Specif......
  • 使用 Python + Beautiful Soup 抓取任何包含 5 个数字的字符串
    我住在德国,那里的邮政编码在大多数情况下都是5位数字。53525。我真的很想使用beautifulSoup从网站中提取该信息。我是Python/BeautifulSoup的新手,我不知道如何将“查找连续的每5个数字+“空格””翻译成Python语言。importrequestsimporturllib.re......