在 Python 中,如何从具有相对路径的祖父文件夹导入?
In Python, how can I import from a grandparent folder with a relative path?
想象一个文件夹结构如下:
project/
grandparent.py
folder1/
parent.py
folder2/
sibling.py
current.py
如果我在 current.py
中,我可以从其他文件 using relative paths 中导入,如下所示:
from .sibling import *
from ..parent import *
如何从 grandparent.py
导入?
(我试过 ...grandparent
和 ../..grandparent
)
创建一个 Python 包
作为确保某种程度的安全性的手段 - 这样 Python 模块就无法访问不受欢迎的区域 - 通常禁止从 parents 或 grandparents 导入。 .. 除非你创建一个包。
幸运的是,在 Python 中,创建包是 crazy-easy。您只需要在每个 folder/directory 中添加一个 __init__.py
文件,您希望将其视为包的一部分。而且,__init__.py
文件 甚至不需要包含任何内容。您只需要存在(可能为空)文件即可。
例如:
#current.py
from folder1.grandparent import display
display()
#grandparent.py
def display():
print("grandparent")
# ├── folder1
# │ ├── __init__.py
# │ ├── folder2
# │ │ ├── __init__.py
# │ │ └── folder3
# │ │ ├── __init__.py
# │ │ └── current.py
# │ └── grandparent.py
后续步骤
这不在 OP 的问题中,但高度相关且值得一提:如果您导入 目录 而不是模块(文件),那么您将导入 __init__.py
文件。例如,
import folder1
实际上是在 folder1
目录中导入 __init__.py
文件。
最后,double-underscore用的太频繁了,简称为dunder。所以说话的时候可以说"dunder init"来指代__init__.py
.
current.py
import os
import sys
FILE_ABSOLUTE_PATH = os.path.abspath(__file__) # get absolute filepath
CURRENT_DIR = os.path.dirname(FILE_ABSOLUTE_PATH) # get directory path of file
PARENT_DIR = os.path.dirname(CURRENT_DIR) # get parent directory path
BASE_DIR = os.path.dirname(PARENT_DIR) # get grand parent directory path
# or you can directly get grandparent directory path as below
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(BASE_DIR) # append the path to system
import grandparent
from folder1 import parent # this way you can import files from parent directory too instead of again appending it to system path
想象一个文件夹结构如下:
project/
grandparent.py
folder1/
parent.py
folder2/
sibling.py
current.py
如果我在 current.py
中,我可以从其他文件 using relative paths 中导入,如下所示:
from .sibling import *
from ..parent import *
如何从 grandparent.py
导入?
(我试过 ...grandparent
和 ../..grandparent
)
创建一个 Python 包
作为确保某种程度的安全性的手段 - 这样 Python 模块就无法访问不受欢迎的区域 - 通常禁止从 parents 或 grandparents 导入。 .. 除非你创建一个包。
幸运的是,在 Python 中,创建包是 crazy-easy。您只需要在每个 folder/directory 中添加一个 __init__.py
文件,您希望将其视为包的一部分。而且,__init__.py
文件 甚至不需要包含任何内容。您只需要存在(可能为空)文件即可。
例如:
#current.py
from folder1.grandparent import display
display()
#grandparent.py
def display():
print("grandparent")
# ├── folder1
# │ ├── __init__.py
# │ ├── folder2
# │ │ ├── __init__.py
# │ │ └── folder3
# │ │ ├── __init__.py
# │ │ └── current.py
# │ └── grandparent.py
后续步骤
这不在 OP 的问题中,但高度相关且值得一提:如果您导入 目录 而不是模块(文件),那么您将导入 __init__.py
文件。例如,
import folder1
实际上是在 folder1
目录中导入 __init__.py
文件。
最后,double-underscore用的太频繁了,简称为dunder。所以说话的时候可以说"dunder init"来指代__init__.py
.
current.py
import os
import sys
FILE_ABSOLUTE_PATH = os.path.abspath(__file__) # get absolute filepath
CURRENT_DIR = os.path.dirname(FILE_ABSOLUTE_PATH) # get directory path of file
PARENT_DIR = os.path.dirname(CURRENT_DIR) # get parent directory path
BASE_DIR = os.path.dirname(PARENT_DIR) # get grand parent directory path
# or you can directly get grandparent directory path as below
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(BASE_DIR) # append the path to system
import grandparent
from folder1 import parent # this way you can import files from parent directory too instead of again appending it to system path