我有一个用于存放客户端代码的文件夹、一个用于存放服务器代码的文件夹以及一个用于存放在它们之间共享的代码的文件夹
Proj/
Client/
Client.py
Server/
Server.py
Common/
__init__.py
Common.py
如何从 Server.py 和 Client.py 导入 Common.py?
Python 2.6 和 3.x 支持适当的相对导入,您可以避免做任何黑客行为。通过这种方法,您知道您正在获得relative导入而不是absolute导入。 '..' 的意思是,转到我上面的目录:
from ..Common import Common
需要注意的是,只有当您从包的outside将Python作为模块运行时,这才有效。例如:
python -m Proj
这种方法在某些情况下仍然很常用,在这些情况下,您实际上并没有“安装”软件包。例如,它很受 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”模块。
有趣的是,我刚刚遇到了同样的问题,我通过以下方式完成了这项工作:
结合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
过程,
这里讨论了同样的问题,希望有帮助!
做相对导入绝对没问题!这是我所做的:
#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
默认的导入方法已经是“相对”的,来自 PYTHONPATH。 PYTHONPATH 默认情况下与原始源文件的文件夹一起指向某些系统库。如果使用 -m 运行模块,当前目录将添加到 PYTHONPATH 中。因此,如果程序的入口点位于 Proj 内部,那么使用
import Common.Common
应该可以在 Server.py 和 Client.py 中工作。
不要进行相对导入。它不会按照你想要的方式工作。
假设我们在当前工作目录中运行
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
python3 path/to/file.py
)。import.py
提到了导入.math
.math
表示“在当前包中查找名为 math 的模块/包”$ python3 second-karma/import.py
时,我正在执行一个模块,而不是一个包。因此 python 不知道 .
在这种情况下意味着什么python3 -m second_karma.import
import.py
属于父包 second_karma
,因此您的相对导入将起作用。那些
__init__.py
是必需的,如果您没有它们,则必须先创建它们。
README.md
以获得更好的理解我使用的方法与上面提到的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