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

5
在Python中,我试图从“last”函数所在的目录访问文件。
例如,假设我有以下文件:
C:/
    foo.py
    package/
        helper.py
        text.md

foo.py有:

from package import helper

helper.edit_file("text.md")

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.")

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

当我直接从helper.py运行edit_file("text.md")时,它能正确地写入到package/text.md中。然而,当我运行foo.py时,它并不能写入到package/text.md,而是在与foo.py相同的目录级别下创建了一个新的text.md。我猜测这是因为它正在从foo.py所在的绝对路径获取。

是否可能仅从helper.py获取绝对路径,以便无论对edit_file(file_location)进行原始调用的位置在哪里,它都始终将写入到package/text.md?

1个回答

2
我认为edit_file()中的file_location含义不明确 - 它必须是完整路径,或者是稍后添加到某个目录中的文件名。此外,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.")

您还可以为软件包中的Markdown文件设置特定目录 - 通常不要写入代码所在的文件夹。您可以通过调用dirname或Python 3.6+中的Path(__file__).parents [n]来导航到项目根目录。
尤其是在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.")

1
完全支持这种方法。需要记住的一点是,在Python 2.7上,__file__ 对于主要的python程序并没有什么帮助,而只有在它导入的python文件上。也就是说,我的main.py文件显示为main.py,没有目录位置,而导入的某些东西具有完整路径。 - JL Peyret
2
sys.argv[1] 在主程序中可能会有所帮助,并且提醒 OP 不要将文件写入代码目录是一个非常好的建议,因为那可能是巨大的安全漏洞。 - JL Peyret

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接