为什么 heroku 在 运行 我的程序时无法获取我文件夹中的文本文件?

Why can't heroku get the text files on my folder while running my program?

我正在用 python 做一个简单的 discord 机器人,我正在使用 heroku 来托管它。我有一些 return 大文本的命令,所以我将这些文本放在单独的 .txt 文件中,并将所有这些文件组织在一个名为“文件”的文件夹中。然后我使用代码访问和读取这些文件。当我托管机器人时一切正常,但 heroku 在托管时总是 return 出现“FileNotFoundError”。

完整的错误信息:

Ignoring exception in command helpie:
Traceback (most recent call last):
File "/app/.heroku/python/lib/python3.10/site-packages/discord/ext/commands/core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "/app/main.py", line 27, in helpie
helpmessage = open(".\files\helpMessage.txt", "r", encoding = "utf-8")
FileNotFoundError: [Errno 2] No such file or directory: '.\x0ciles\helpMessage.txt'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/app/.heroku/python/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "/app/.heroku/python/lib/python3.10/site-packages/discord/ext/commands/core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/app/.heroku/python/lib/python3.10/site-packages/discord/ext/commands/core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: FileNotFoundError: [Errno 2] No such file or directory: '.\x0ciles\helpMessage.txt'

这是使用 .txt 文件的命令之一。此代码位于 heroku 正在读取的 main.py 文件中。

@bot.command()
async def helpie(ctx):
    helpmessage = open(".\files\helpMessage.txt", "r", encoding = "utf-8")
    await ctx.send(helpmessage.read())
    helpmessage.close()

这是程序的根文件夹及其所有文件的树:

C:.
│   .gitignore
│   main.py
│   Procfile
│   README.md
│   requirements.txt
│   runtime.txt
│
├───.vscode
└───files
        bot icon.png
        geraldoMessage.txt
        helpMessage.txt

不知道有没有必要,我会把“requirements.txt”和“Procfile”的内容也包括进去。

过程文件:

worker: python main.py

requirements.txt

discord.py
asyncio

感谢您的帮助。

我怀疑更完整的错误是这样的:

No such file or directory: '.\x0ciles\helpMessage.txt'

眼前的问题可能是您通过在字符串中包含 \f 不小心使用了 escape sequence,这表示 ASCII 换页。

请注意路径已损坏。您可以在这里给我们一个原始字符串:

open(r".\files\helpMessage.txt", "r", encoding = "utf-8")
#    ^ raw string

或者您可以更改定义该路径的方式。正斜杠比反斜杠更安全,使用 pathlibos.path 将各个路径组件连接在一起更安全。

我认为这不是您的直接问题,但您的路径也与工作目录相关。我建议将它与已知位置相关联,例如项目的根目录。

将它们放在一起,尝试这样的事情(使用 pathlib):

from pathlib import Path

# This will point to the right directory no matter what the working directory is
root_path = Path(__file__).resolve().parent


@bot.command()
async def helpie(ctx):
    helpmessage = open(root_path / "files" / "helpMessage.txt", "r", encoding = "utf-8")
    #                            ^         ^ safely joining components
    #                  ^^^^^^^^^ known path
    await ctx.send(helpmessage.read())
    helpmessage.close()

或像这样(使用os.path):

import os.path

root_path = os.path.dirname(os.path.abspath(__file__))


@bot.command()
async def helpie(ctx):
    helpmessage = open(os.path.join(root_path, "files", "helpMessage.txt"), "r", encoding = "utf-8")
    #                               ^^^^^^^^^ known path
    #                  ^^^^^^^^^^^^ safely joining components
    await ctx.send(helpmessage.read())
    helpmessage.close()