简体   繁体   English

在python中导入项目文件

[英]Importing project files in python

I mostly worked on PHP where it was really easy to import classes specially after composer. 我主要在PHP上工作,在PHP上导入类非常容易,尤其是在作曲家之后。 But I am having hard times applying same directory structure in Python project. 但是我很难在Python项目中应用相同的目录结构。

I have the following directory structure. 我有以下目录结构。

backend commands indices.py backup.py etc.py components mapping product.py storage Es.py interfaces StorageInterface.py IndexInterface.py

My commands folder is basically the files i will run through cli where as the components will hold the actual business logic and interfaces just contains the ABCs for components. 我的命令文件夹基本上是我将通过cli运行的文件,因为这些组件将保存实际的业务逻辑,而接口仅包含这些组件的ABC。

I have to do several imports throughout the code some times from same folder sometimes from subfolder and sometimes same level another folder. 我有时必须从同一文件夹(有时是子文件夹,有时是同一级别的另一个文件夹)对代码进行多次导入。

For example in my indices.py file i have this import 例如在我的indexs.py文件中,我有此导入

from components.storage.Es import Es

This gives me 这给我

root@07fc62bd3c97:/backend/commands# python indices.py --help 
Traceback (most recent call last):   
File "indices.py", line 1, in <module> from components.storage.Es import Es ImportError: No module named components.storage.Es

I have gone through other answers on SO and found really dirty solutions of putting sys and os modules and adding files in runtime. 我在SO上经历了其他答案,发现了放置sys和os模块以及在运行时添加文件的真正肮脏的解决方案。 This could be okay when its 1 2 files but managing the whole project looks really bad. 当它的1 2文件但是管理整个项目看起来真的很糟糕时,这可能还可以。

My questions here are 我的问题是

1 - Am i following the pythonic way of managing a project 2 - How can i access all my classes files in a neat way 1-我是否遵循管理项目的pythonic方式2-如何以一种整洁的方式访问我所有的类文件

Thanks 谢谢

You need __init__.py files in the commands , components , mapping , storage , and interfaces subdirectories in order for those directories and the files contained within them to be considered modules by python. 您需要在commandscomponentsmappingstorageinterfaces子目录中使用__init__.py文件,以便这些目录及其中包含的文件被python视为模块。 Also, having individual modules which have the same name as some class which is defined inside of them is not really pythonic. 同样,拥有与内部定义的某些类同名的各个模块并不是真正的pythonic。 For example, it's better to have an interfaces module defined by an interfaces.py file which contains both interface classes than to have two files named StorageInterface.py and IndexInterface.py which each contain a class definiton (I'm assuming that's what you're doing there). 例如,最好是由一个包含两个接口类的interfaces.py文件定义一个interfaces模块,而不要拥有两个分别包含一个类定义的名为StorageInterface.pyIndexInterface.py文件(我假设这就是您所需要的)。重新在那里)。

Also, it matters what directory you start the python process from. 另外,从哪个目录开始python进程也很重要。 In order for that import path to be meaningful, I'm pretty sure you'd need to start the python process from within the backend directory. 为了使导入路径有意义,我很确定您需要从backend目录中启动python进程。 Or you'd need to add the filesystem paths of the components , commands , etc. subdirectories to python's module path via the PYTHONPATH env var or by some other method. 或者,您需要通过PYTHONPATH env var或通过其他方法,将componentscommands等子目录的文件系统路径添加到python的模块路径。

Treat your entire backend folder like a package. 将您的整个backend文件夹视为一个包。 If you're using legacy Python (Python 2), you'll need to put __init__.py files in all the folders so they are importable as subpackages. 如果您使用的是旧版Python(Python 2),则需要在所有文件夹中放置__init__.py文件,以便将它们作为子包导入。 You'd need to either tweak your imports to then be from backend.components.storage.Es , or from ..components.storage.Es (relative imports). 您需要调整导入,然后from backend.components.storage.Esfrom ..components.storage.Es (相对导入)进行调整。

Then, because it's all a package, you'll find that you can't go into a subfolder and execute code. 然后,因为它们都是包,所以您会发现无法进入子文件夹并执行代码。 The fix then is to run the code (eg backend/commands/backup.py ) by using the -m module flag: python -m backend.commands.backup from the folder containing backend . 解决方法是使用-m模块标志运行代码(例如backend/commands/backup.py ):包含backend的文件夹中的python -m backend.commands.backup If you want, you can add an entrypoint later by making a setup.py that would turn it into a prettier command. 如果需要,您可以稍后通过创建setup.py来添加入口点,该入口点会将其转变为更漂亮的命令。

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

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