【问题标题】:Why is python assuming my path is the project root, which is two directory levels up?为什么 python 假设我的路径是项目根目录,它是两个目录级别?
【发布时间】:2019-06-25 13:15:22
【问题描述】:

我正在 Lynda 上做一些 Python 学习教程。正如人们所期望的那样,本教程的脚本在与脚本相同的目录中创建文件。

不过,无论出于何种原因,我的安装正在创建文件并希望在项目根目录或两个目录中读取文件(使用路径对象)。

我正在运行的脚本是C:\Users\user\Development\Ex_Files_Learning_Python\Exercise Files\Ch4

脚本如下所示:

import os
from os import path
import datetime
from datetime import date, time, timedelta
import time


def main():
  # Print the name of the OS
  print(os.name)

  # Check for item existence and type
  print("Item exists: " + str(path.exists("textfile.txt")))
  print("Item is a file: " + str(path.isfile("textfile.txt")))
  print("Item is a directory: " + str(path.isdir("textfile.txt")))
  # Work with file paths
  print("Item path" + str(path.realpath("textfile.txt")))
  print("Item path and name: " + str(path.split(path.realpath("textfile.txt"))))

  # Get the modification time


  # Calculate how long ago the item was modified



if __name__ == "__main__":
  main()

它的输出是

nt
Item exists: False
Item is a file: False
Item is a directory: False
Item pathC:\Users\user\Development\Ex_Files_Learning_Python\textfile.txt
Item path and name: ('C:\\Users\\user\\Development\\Ex_Files_Learning_Python', 'textfile.txt')

如您所见,它假定它的路径是项目根目录,向上两个目录。我在之前的练习中遇到了同样的问题,创建了一个文件。当我在文件对象上使用 open() 时,它在项目的根目录中创建了文件。

感谢任何指针。

更新:我已经确定这是因为我使用的是 VSCode 终端。如何指示 VSCode 终端从我正在编辑和调试的文件的 cwd 而不是项目根目录运行程序?

为了记录,这是我的调试器的launch.json

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File (Integrated Terminal)",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        },
        {
            "name": "Python: Remote Attach",
            "type": "python",
            "request": "attach",
            "port": 5678,
            "host": "localhost",
            "pathMappings": [
                {
                    "localRoot": ".",
                    "remoteRoot": "."
                }
            ]
        },
        {
            "name": "Python: Module",
            "type": "python",
            "request": "launch",
            "module": "enter-your-module-name-here",
            "console": "integratedTerminal"
        },
        {
            "name": "Python: Django",
            "type": "python",
            "request": "launch",
            "program": "${workspaceFolder}/manage.py",
            "console": "integratedTerminal",
            "args": [
                "runserver",
                "--noreload",
                "--nothreading"
            ],
            "django": true
        },
        {
            "name": "Python: Flask",
            "type": "python",
            "request": "launch",
            "module": "flask",
            "env": {
                "FLASK_APP": "app.py"
            },
            "args": [
                "run",
                "--no-debugger",
                "--no-reload"
            ],
            "jinja": true
        },
        {
            "name": "Python: Current File (External Terminal)",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "externalTerminal"
        }
    ]
}

【问题讨论】:

  • 如果你在C:\users\user\Development\Ex_Files_Learning_Python 并做python "Exercise Files\Ch4.py",你会得到这种行为。如果您愿意,可以重新根到 Python 文件:os.chdir(__file__)
  • 谢谢,查看我的更新@AdamSmith 这是默认为根目录的 VSCode 终端。现在想弄清楚如何解决这个问题。另一方面,我可能是错的,因为我没有尝试过,但你的重新root 解决方法不会因为它尝试将目录更改为文件路径而不是目录而失败吗?
  • 哦,是的,它完全可以。 os.chdir(os.path.dirname(__file__)) 然后:)。有一种方法可以更改 vscode 中的这些设置,但这取决于您加载文件的方式(它是项目的一部分等)
  • @AdamSmith 我将它作为项目的一部分打开。我打开了目录,然后从侧边栏打开项目文件。

标签: python python-3.x visual-studio-code


【解决方案1】:

根据https://code.visualstudio.com/docs/python/settings-reference

python.terminal.executeInFileDir

指示是否在文件目录而不是当前文件夹中运行文件。

所以大概只是将python.terminal.executeInFileDir 设置为true

【讨论】:

  • 我现在意识到这会影响终端窗口,但不会影响调试器。你的答案是对的,但我将用另一个关于更改调试器的答案来更新。
【解决方案2】:

如果您从终端运行脚本,您可能正在运行:

python "Exercise Files\Ch4\my_script.py"

或类似的东西。

相反,先更改文件夹,然后在终端上运行它:

cd "Exercise Files\Ch4"
python my_script.py

或者,为了避免所有这些手动目录切换,显式更改脚本中的工作目录。

【讨论】:

  • 我已经确定这是因为我使用的是 VSCode 终端。如何指示 VSCode 终端从我正在编辑和调试的文件的 cwd 而不是项目根目录运行程序?
  • 最好明确指定文件路径:)
  • 您说“发生这种情况是因为我使用的是 VSCode 终端”,但您并没有告诉我们您到底在做什么。我的建议是您可能自己从该工作目录启动 Python,这就是您的脚本发现自己在该目录运行的原因。有关如何使用 VSCode 设置 Python 脚本环境的更多信息,请查看code.visualstudio.com/docs/python/python-tutorial
  • @Grismar 我告诉你你是对的。终端正在从项目根目录启动脚本。这意味着我现在必须让它从文件的 cwd 运行。感谢您提供该文档。我想我会阅读它并发布我找到的任何答案作为我自己的答案。
  • 我很抱歉,但没有暗示任何冒犯,我不喜欢在回答问题时被指责为煤气灯。我建议您重新阅读以上内容,以确认您的指控是没有根据的。
【解决方案3】:

这是我的错,因为我没有说明我试图在 VSCode 中修改调试器终端。 @Adam Smith 的答案适用于处理标准终端的大多数情况。

但是,如果您尝试从调试器运行文件,答案是将“cwd”设置为空字符串,即在launch.json 中的“”(当前调试器配置)

https://code.visualstudio.com/docs/python/debugging#_cwd

【讨论】:

    【解决方案4】:

    您需要使用的是__file__ 内置变量,Python 将其与当前 Python 文件名相关联。

    what does the __file__ variable mean/do?

    如果您使用的是 Python 3,这应该可以工作。

    pathlib.Path 在 Python 3 上,用于操作文件路径。

      from pathlib import Path                            
      myfilepath = Path(Path(__file__).resolve()).parent / "textfile.txt"
                        ^            ^
                        find the currrent script location
                                                 ^ get its parent directory
                                                            ^ add your file name
    

    这是脚本

    import os
    from os import path
    import datetime
    from datetime import date, time, timedelta
    import time
    
    
    def main():
      # Print the name of the OS
      print(os.name)
    
      from pathlib import Path
      myfilepath = Path(Path(__file__).resolve()).parent / "textfile.txt"
    
      # Check for item existence and type
      print("Item exists: " + str(path.exists(myfilepath)))
      print("Item is a file: " + str(path.isfile(myfilepath)))
      print("Item is a directory: " + str(path.isdir(myfilepath)))
      # Work with file paths
      print("Item path" + str(path.realpath(myfilepath)))
      print("Item path and name: " + str(path.split(path.realpath(myfilepath))))
    
      # Get the modification time
    
    
      # Calculate how long ago the item was modified
    
    main()
    

    输出:

    posix
    Item exists: True
    Item is a file: True
    Item is a directory: False
    Item path/Users/jluc/kds2/wk/explore/textfile.txt
    Item path and name: ('/Users/jluc/kds2/wk/explore', 'textfile.txt')
    

    如果您使用的是 Python 2,则改用它可以获得相同的结果:

    os.path.join("foo", "bar") 将在 Windows 上返回 foo\bar 或在 Linux/macO 上返回 foo/bar

    #from pathlib import Path
    myfilepath = os.path.join(os.path.dirname(__file__), "textfile.txt")
                              ^ get parent directory
                                                         ^ append your filename
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-21
      • 2015-04-19
      • 1970-01-01
      • 2015-08-22
      • 1970-01-01
      相关资源
      最近更新 更多