代码之家  ›  专栏  ›  技术社区  ›  user9074332

Python 3-发布导入模块-从父目录-包含文件描述符

  •  -1
  • user9074332  · 技术社区  · 6 年前

    我无法从文件的父目录简单导入python3模块。我可以让模块导入从父目录运行,而不会出现问题 直到 我在要导入的文件中引入了一个文件描述符。

    下面的示例1是一个“运行良好”的场景,2是我希望得到建议的问题场景。

    #1-工作正常

    应用程序目录结构:

    ├── app
    │   └── app.py
    ├── config.py
    

    文件内容:

    # app.py
    import sys
    sys.path.insert(0, '../')
    from config import Config as conf
    
    foo = conf.foo
    
    if __name__ == '__main__':
        print('hello from app main')
        print(f'foo is --> {foo}')
    
    
    #config.py
    class Config():
        foo = 'bar'
    

    $ pwd
    app/
    $ python app.py
    hello from app main
    foo is --> bar
    

    #2-不工作/失败

    ├── app
    │   └── app.py
    ├── config.py
    └── foo.txt <-- **Introduced new file here**
    

    文件内容:

    # app.py
    import sys
    sys.path.insert(0, '../')
    from config import Config as conf
    
    foo = conf.foo
    
    if __name__ == '__main__':
        print('hello from app main')
        print(f'foo is --> {foo}')
    
    # config.py
    class Config():
        with open('foo.txt', 'rt') as f:
            foo = f.readline().rstrip()   
    
    # foo.txt
    bar
    

    运行它:

    $ pwd
    app/
    
    $ python app.py
    Traceback (most recent call last):
      File "app.py", line 3, in <module>
        from config import Config as conf
      File "../config.py", line 1, in <module>
        class Config():
      File "../config.py", line 2, in Config
        with open('foo.txt', 'rt') as f:
    FileNotFoundError: [Errno 2] No such file or directory: 'foo.txt'
    

    我在这里做错什么了?请注意foo.txt 实际上存在于父目录中,尽管有“FileNotFoundError”错误消息。

    $ cat ../foo.txt
    bar
    

    1 回复  |  直到 6 年前
        1
  •  1
  •   bruno desthuilliers    6 年前

    我在这里做错什么了?

    您使用的是相对路径。这:

    open("foo.txt")
    

    将在 current working directory ,无论它在此时此刻是什么(这意味着它可以是任何东西,你永远不应该对它做任何假设)。

    请注意,尽管有“FileNotFoundError”错误消息,foo.txt实际上确实存在于父目录中。

    是的,它存在于父目录中,但不在 现在的 目录。

    这里的标准解决方案是使用 os.path __file__ 魔法变量:

    # config.py
    import os
    
    def read_foo():
        # build the full path to the current file
        here = os.path.abspath(__file__)
        # extract the directory path
        dirpath = os.path.dirname(here)
        # foo.txt is supposed to be in the same directory:
        foopath = os.path.join(dirpath, "foo.txt")
        with open(foopath) as f:
            return f.readline().rstrip()
    

    现在你可以放心地打电话了 config.read_foo() 从任何其他模块,无论当前工作目录是什么。

    class 语句块可能不是一个好主意-不是说它在Python中是非法的,但它确实是一种设计味道。。。