简体   繁体   English

如何从OSX上的Python 3.5中的另一个文件夹导入python文件?

[英]How to import a python file from another folder in Python 3.5 on OSX?

I use Python 3.5 and my project structure is like this: 我使用Python 3.5,我的项目结构如下:

Project/
    App/
        myApp.py
    Libraries/
        myLibA.py
        myLibB.py

I want to import myLibA.py in myApp.py 我想导入myLibA.pymyApp.py

If I simply write from Libraries import myLibA I end up with this error : 如果我只是from Libraries import myLibA编写from Libraries import myLibA出现此错误:

ImportError: No module named Libraries. ImportError:没有名为库的模块。

I found the Q/A Importing files from different folder in Python , from which I adapted my own solution, adding this at the beginning of myApp.py in order to add my Project folder to the Python Path : 我找到了Q / A 从Python的其他文件夹导入文件 ,从中改编了自己的解决方案,将其添加到myApp.py的开头,以便将Project文件夹添加到Python路径:

import sys
sys.path.insert(0, sys.path[0] + "..")

This worked well on Windows, but when I run myApp.py from the same project on OSX (10.9) I see the same error message, my module is not found. 这在Windows上运行良好,但是当我在OSX(10.9)上的同一项目中运行myApp.py ,我看到相同的错误消息,但找不到我的模块。

To reproduce my issue it's very simple. 重现我的问题很简单。 Just fill the Python files like this : 只需像这样填充Python文件:

myApp.py : myApp.py

import sys
sys.path.insert(0, sys.path[0] + "..")

from Libraries import myLibA

if __name__ == '__main__':
    myLibA.print_hello()

myLibA.py : myLibA.py

def print_hello():
    print("Hello")

I don't understand why the Python Path method doesn't work here. 我不明白为什么Python Path方法在这里不起作用。 Anyway, I'm looking for a solution that keeps the Python file compatible with Windows and that is contained in the sources (in the Python files). 无论如何,我正在寻找一种使Python文件与Windows兼容并包含在源代码(Python文件中)中的解决方案。 I've seen a few console hooks but I'm not satisfied with that because I want to be able to clone the project on any OSX/Windows PC with Python 3.5, and just run myApp.py. 我已经看到了一些控制台挂钩,但是对此我感到不满意,因为我希望能够在任何使用Python 3.5的OSX / Windows PC上克隆项目,然后运行myApp.py。 I'm looking for a solution that doesn't involve any library not natively present in Python 3.5. 我正在寻找一种解决方案,该解决方案不涉及Python 3.5中本身不存在的任何库。

Is there another way to achieve this ? 还有另一种方法可以实现这一目标吗?

(If not, is it because it is somehow not pythonic to organize a project like this? As a C developer I might have the wrong approach) (如果不是,是否是因为以某种方式组织这样的项目不是pythonic ?作为C开发人员,我可能有错误的方法)

Add __init__.py to your Libraries directory. __init__.py添加到您的Libraries目录中。 That file can be empty, and it magically turns the Libraries directory into a package . 该文件可以为空,并且神奇地将Libraries目录转换为package Now: 现在:

import sys
import os.path
libdir = os.path.dirname(__file__)
sys.path.append(os.path.split(libdir)[0])   

from Libraries import myLibA

if __name__ == '__main__':
    myLibA.print_hello()

The __file__ special variable gives the filename of the current script. __file__特殊变量提供当前脚本的文件名。 os.path.dirname() gives the directory it resides in, and os.path.split(libdir)[0] gives its parent directory. os.path.dirname()给出其驻留的目录,而os.path.split(libdir)[0]给出其父目录。 This should work wherever the script is called from. 无论从何处调用脚本,这都应该起作用。

I am using append rather than insert . 我正在使用append而不是insert It is generally advised that user directories are searched last, and also append is more efficient than insert in the C Python implementation. 通常建议最后搜索用户目录,并且append在C Python实现中比insert更有效。

You should have __init__.py inside every folder that you want to import. 您要导入的每个文件夹中都应包含__init__.py Also a common project structure for a python project is this: 同样,python项目的常见项目结构是:

Project/ 
Libraries/         <-- this will contain app specific code (Libraries)
    __init__.py
    myLibA.py
    myLibB.py
main.py

Where main.py will contain the entry code of you app, just like C's main(), for example 例如main.py将包含您应用的输入代码,例如C的main()

from Libraries import myLibA

if __name__ == '__main__':
    myLibA.print_hello()

No need to tinker with sys.path in runtime. 无需在运行时修改sys.path。

This Question is somewhat similar. 这个问题有点相似。 My favourite answer suggests a project structure like this in your case: 我最喜欢的答案是在您的情况下建议这样的项目结构:

Project/
    myApp.py
    Libraries/
        __init__.py
        myLibA.py
        myLibB.py

With the library code in myLibA.py unchanged the app code and import would look like this: myLibA.py的库代码不变的情况下,应用程序代码和导入将如下所示:

from Libraries import myLibA

if __name__ == "__main__":
    myLibA.print_hello()

Edit 1: 编辑1:

When the requested folder structure is necessary, this change to the myApp.py file: 当需要所请求的文件夹结构时,将此更改为myApp.py文件:

import sys
import os
sys.path.append(os.path.abspath(".."))

works too. 也可以。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM