从 Python 中的相对路径导入[重复]

2025-03-04 08:24:00
admin
原创
95
摘要:问题描述:我有一个用于存放客户端代码的文件夹、一个用于存放服务器代码的文件夹和一个用于存放它们之间共享的代码的文件夹Proj/ Client/ Client.py Server/ Server.py Common/ __init__.py...

问题描述:

我有一个用于存放客户端代码的文件夹、一个用于存放服务器代码的文件夹和一个用于存放它们之间共享的代码的文件夹

Proj/
    Client/
        Client.py
    Server/
        Server.py
    Common/
        __init__.py
        Common.py

如何从 Server.py 和 Client.py 导入 Common.py?


解决方案 1:

编辑于2014年11月(3年后):

Python 2.6 和 3.x 支持正确的相对导入,这样您就可以避免做任何黑客行为。使用此方法,您知道您获得的是相对导入,而不是绝对导入。'..' 表示转到我上级目录:

from ..Common import Common

需要注意的是,这仅在您将 Python 作为模块从包外部运行时才有效。例如:

python -m Proj

原始的 hack 方式

在某些情况下,这种方法仍然很常用,在这种情况下您实际上从未“安装”过您的包。例如,它深受 Django 用户的欢迎。

您可以将 Common/ 添加到您的 sys.path(python 查看以导入内容的路径列表):

import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'Common'))
import Common

os.path.dirname(__file__)只为您提供当前 python 文件所在的目录,然后我们导航到“Common/”目录并导入“Common”模块。

解决方案 2:

有趣的是,我刚刚遇到了同样的问题,我通过以下方式完成了这项工作:

结合 linux 命令ln,我们可以让事情变得简单得多:

1. cd Proj/Client
2. ln -s ../Common ./

3. cd Proj/Server
4. ln -s ../Common ./

现在,如果您想some_stuff从文件:导入Proj/Common/Common.py到您的文件:Proj/Client/Client.py,就像这样:

# in Proj/Client/Client.py
from Common.Common import some_stuff

并且,同样适用于Proj/Server,也适用于setup.py过程,
这里讨论的相同问题,希望它有所帮助!

解决方案 3:

执行相对导入绝对没问题!下面是我所做的:

#first change the cwd to the script path
scriptPath = os.path.realpath(os.path.dirname(sys.argv[0]))
os.chdir(scriptPath)

#append the relative location you want to import from
sys.path.append("../common")

#import your module stored in '../common'
import common.py

解决方案 4:

不要进行相对导入。

来自PEP8:

强烈不建议使用相对导入进行包内导入。

将所有代码放入一个超级包(即“myapp”),并使用子包来存放客户端、服务器和通用代码。

更新:
Python 2.6 和 3.x 支持正确的相对导入 (...) ”。有关更多详细信息,请参阅Dave 的回答。

解决方案 5:

默认导入方法已经是“相对”的,来自 PYTHONPATH。默认情况下,PYTHONPATH 是一些系统库以及原始源文件的文件夹。如果您使用 -m 运行模块,则当前目录将添加到 PYTHONPATH。因此,如果您的程序的入口点位于 Proj 内部,那么使用import Common.Common应该可以在 Server.py 和 Client.py 中工作。

不要进行相对导入。它不会按你希望的方式工作。

解决方案 6:

我使用的方法与上面提到的Gary Beardsley 的方法类似,但略有不同。

文件名:Server.py

import os, sys
script_path = os.path.realpath(os.path.dirname(__name__))
os.chdir(script_path)
sys.path.append("..")
# above mentioned steps will make 1 level up module available for import
# here Client, Server and Common all 3 can be imported.

# below mentioned import will be relative to root project
from Common import Common
from Client import Client

解决方案 7:

创建一个简单的示例

假设我们ls -R在当前工作目录中运行,结果如下:

./second_karma:
enemy.py  import.py  __init__.py  math

./second_karma/math:
fibonacci.py  __init__.py

我们运行这个命令$ python3 second-karma/import.py

*init.py是一个空文件但它应该存在。*

现在让我们看看里面有什么second-karma/import.py

from .math.fibonacci import Fibonacci
fib = Fibonacci()
print(fib.get_fibonacci(15))

里面有什么second_karma/math/fibonacci.py

from ..enemy import Enemy
class Fibonacci:
    enemy: Enemy

    def __init__(self):
        self.enemy = Enemy(150,900)
        print("Class instantiated")
    
    def get_fibonacci(self, which_index: int) -> int:
        print(self.enemy.get_hp())
        return 4

现在最后一个文件是second_karma/enemy.py

class Enemy:
    hp: int = 100
    attack_low: int = 180
    attack_high: int = 360

    def __init__(
            self, 
            attack_low: int,
            attack_high: int) -> None: 
        self.attack_low = attack_low
        self.attack_high = attack_high

    def getAttackPower(
            self) -> {"attack_low": int, "attack_high": int}:
        return {
            "attack_low": self.attack_low,
            "attack_high": self.attack_high
        }

    def get_hp(self) -> int:
        return self.hp

现在简单回答一下为什么它不起作用:

  • Python 有一个包的概念,它基本上是一个包含一个或多个模块以及零个或多个包的文件夹。

  • 当我们启动python时,有两种方法可以做到:

    • 要求 python执行特定模块python3 path/to/file.py)。

    • 要求 python执行一个包

  • 问题是import.py提到进口.math

    • 在这种情况下,意思.math是“在当前包中查找名为 math 的模块/包”

    • 麻烦:

      • 当我执行时,$ python3 second-karma/import.py我正在执行一个模块,而不是一个包。因此 python 不知道.这个上下文中的意思

      • 使固定:

      python3 -m second_karma.import
      
      • 现在import.py是父包second_karma,因此您的相对导入将起作用。

重要提示:

这些__init__.py都是必需的,如果您还没有,您必须先创建它们。

github 上的一个例子

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   4008  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2751  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   86  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   97  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   85  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用