Python - 调用子模块时的相对文件位置

Oli*_*ung 5 python relative-path

在Python中,我试图从"最后"函数(缺少更好的单词)所在的目录中访问文件.

例如,假设我有以下文件:

C:/
    foo.py
    package/
        helper.py
        text.md
Run Code Online (Sandbox Code Playgroud)

foo.py有:

from package import helper

helper.edit_file("text.md")
Run Code Online (Sandbox Code Playgroud)

helper.py有:

from os.path import abspath

def edit_file(file_location):
    with open(abspath(file_location), "w") as file:
        file.write("This file has been written to.")
Run Code Online (Sandbox Code Playgroud)

而text.md只是一个空文本文件.

当我直接edit_file("text.md")从helper.py 运行时,它正确地写入package/text.md.但是,当我运行foo.py时,它不会写入package/text.md,而是在与foo.py相同的目录级别创建一个新的text.md.我假设发生这种情况是因为它从foo.py所在的位置开始采用绝对路径.

是否有可能只从helper.py获取绝对路径,这样它总是写入package/text.md,无论原始调用在edit_file(file_location)哪里?

Evg*_*eny 2

我认为file_locationinedit_file()是不明确的 - 它必须是完整路径,或者是稍后添加到某个目录的文件名。还会abspath()在给定文件上创建绝对路径,但不会为您选择目录。

在您的情况下,您需要为文件设置一个目录并显式创建完整路径。查找给定文件的目录名的常用方法是os.path.dirname(os.path.abspath(__file__))__file__它是与单个文件关联的 python 内部变量,它保存文件路径。

helper.py 可以是这样的:

import os
BASEDIR = os.path.dirname(os.path.abspath(__file__))

def make_path(filename, directory=BASEDIR):
    return os.path.join(directory, filename) 

def edit_file(filename):
    with open(make_path(filename), "w") as file:
        file.write("This file has been written to.")
Run Code Online (Sandbox Code Playgroud)

您还可以为包中的 markdown 文件设置特定目录 - 通常您不会写入代码所在的文件夹。您可以通过调用dirnamePath(__file__).parents[n]在 Python 3.6+ 中实现导航到项目根目录。

特别是在 Python 3.6 中,helper.py 中的代码更加简洁:

from pathlib import Path 

def update(filename: str, text: str):
    path = Path(__file__).parent / filename 
    path.write_text(text)

update("text.md", "This file has been written to.")
Run Code Online (Sandbox Code Playgroud)

  • `sys.argv[1]` 可能对 main 有帮助。并且有利于警告OP不要写入代码目录 - 这可能是一个巨大的潜在安全漏洞。 (2认同)