[英]Importing from a relative path in Python
我有一個用於存放客戶端代碼的文件夾、一個存放服務器代碼的文件夾以及一個存放它們之間共享的代碼的文件夾
Proj/
Client/
Client.py
Server/
Server.py
Common/
__init__.py
Common.py
如何從 Server.py 和 Client.py 導入 Common.py?
Python 2.6 和 3.x 支持適當的相對導入,您可以避免做任何 hacky。 使用這種方法,您知道您獲得的是相對導入而不是絕對導入。 '..' 的意思是,轉到我上面的目錄:
from ..Common import Common
需要注意的是,這僅在您從包外部將 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
進程, 這里討論的同樣的問題,希望它有所幫助!
做相對導入是絕對OK的! 這是 little 'ol me 所做的:
#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 中工作。
不要進行相對導入。 它不會按照你想要的方式工作。
我使用的方法與上面提到的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
假設我們在當前工作目錄中運行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
以獲得更好的理解
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.