This is an extract from my fabric script
def create_php_site(name):
"""
Creates a new php installation
"""
from resource.php.git import gitignore
from resource.php.nginx import nginx
when I run it, I get error "ImportError: No module named php.git"
but if I move "from resource.php.git import gitignore " outside of the function, it works. Any ideas?
Each layer of resource.php.git has __init__.py
There is git.py in resource/php/:
gitignore = """.DS_Store
._.DS_Store
"""
You are running into a namespace conflict.
You cannot name your directory resource because there's a standard python module named resource - http://docs.python.org/2/library/resource.html
And so when you declare from resource... all hell breaks loose. Python cannot find php.git because indeed, in the standard resource python module, there's no such functionalities.
I created a similar example but instead renamed resource directory to myresource. Performing the imports then work perfectly. Like this:-
>>> from myresource.php.git import gitignore
>>> gitignore
'my ignore strings'
IMPORTANT
Please also make sure that you have an __init__.py file in your myresource directory.
Related
I am working on some python project (2.7) and I have issue with imports. When I run main.py it start scripts from tests folder etc. and save output to logs and everything works fine.
/root------------
-logs
-staticCfg
-config.py
-tests
-systemTest
-scrypt1.py
-scrypt2.py
-userTest
-uScrypt1.py
main.py
My static variables (email, name etc.) are located in config.py. I need to import config.py in scrypt1.py or scrypt2.py. I tryed adding __init__.py to tests, systemTest and staticCfg folder but I always get an error.
In my scrypt1.py:
import staticCfg as cfg
...
or
from staticCfg import *
...
I get the error:
ImportError: No module named staticCfg
The import mechanism of Python can be a bit tricky.
You can refer to the documentation for more information: Python Import Mechanism
When you use absolute imports (your import does not start with a .) as you do, the import path will start from your main script (the one you launch). In your case, it's scrypt1.py. So starting from this location, python can't find the package staticCfg.
For me, the simplest solution is to create a main script in your root directory and call scrypt1.py from there (imported using from tests.systemTet import scrypt1.py). In this case, the base package will be your root folder and you will have access to the package staticCfg from all your script files as you wanted to do.
you may add root folder to PYTHONPATH.
I have created a folder named C:\Python27\Lib\site-packages\perso and inside I have put a file mymodule.py. The goal is to have this module accessible from any future Python script.
Let's do a D:\My Documents\test.py file:
import mymodule #fails
import perso.mymodule #fails
Why does it fail? How to import a module from C:\Python27\Lib\site-packages\perso? What are the best practice for using user-modules in all Python scripts of the same computer?
check PythonPath
create __init__.py to use perso as package
Python Modules:
In order to create a module you can do the following:
under <Python_DIR>\Lib\site-packages:
put you directory <module>. This directory contains your classes.
In <Python_DIR>\Lib\site-packages\<module> put an init file __init__.py,
This file define what's in the directory, and may apply some logic if needed.
for example:
__all__ = ["class_1", "class_2",].
Than, to import:
from <your_module> import <your_class>
For more information, read this.
Suppose that you create a Python package called app, and it contains a module called foo, which has a function called say_hello that prints out Hello! to the console.
Suppose that you also create a second Python package called boss_app that has a module main. The app and boss_app are in the same directory, and the directory is on the Python path. Also, the __init__ files are all blank. The structure is:
app
__init__.py
foo.py
boss_app
__init__.py
main.py
I want to import app into boss_app.main so that I can call app.foo.say_hello.
I use this command:
import app
app.foo.say_hello()
and I expect to see in the console:
>>>> Hello!
Instead, the behavior I get is that app is imported but it does not have access to foo.
The solution I came up with was to modify app.__init__ so that it contained the following command:
from .foo import *
Now I get the expected behavior.
Is it always necessary to make a custom __init__ for a package if that package is going to be imported from an outside package?
Saying
import app
only runs app/__init__.py and makes everything it initializes available to be used as app.SOMENAME. If you want app.foo module to be available, you need to say import app.foo. This will load the module. A common example of this distinction is probably import os vs import os.path. Just because you say import os, you won't have the contents of os.path package available.
You don't have to break modules into packages, but it helps to avoid module-name collision. It may also help to keep concepts clear in the mind of a user of these modules.
I'm still learning to code better in Python. Therefore I am trying to use some constructions in my programming. Things like name_conventions and structured packaging & modules.
That said I come across an issue which I cannot resolve, it seems.
The structure I chose is as follows:
Core
__init__.py
controller.py
Dashboard
Log
Plugins
Stats
__init__.py
controller.py
Plugin2
Plugin3
Etc..
main.py
In the Core controller.py i am trying to import the Stats(object) class.
I have tried several different ways. In my IDE (Pycharm) it works like a charm ;) When i try to start it via Command Line i get ImportErrors.
I have tried different approaches.
from Plugins.Stats.controller import Stats
from Plugins.Stats import controller
from Plugins.Stats import controller.Stats
from Plugins import Stats.controller
I also tried to put the Stats class into the Plugins.Stats.__init__.py and call it:
from Plugins.Stats import Stats
and I get this:
Traceback (most recent call last):
File "controller.py", line 4, in <module>
from Plugins.Stats.controller import Stats
ImportError: No module named 'Plugins'
The funny thing is... When i try to do the same from main.py.
It does work. So I am really confused. Am I doing something wrong?
Also are there special design patterns to handle imports?
You should add __init__.py file also in the Plugins directory so it will look like
Plugins
__init__.py
Stats
__init__.py
controller.py
You can read more about Python modules here - check out 6.4. Packages
you also can make your module you want to import visible for everyone by adding it to the pythonpath
sys.path.append("/path/to/main_folder")
before this modules are on another namespaces
You will find more info here
First put From plugin import stats, then from stats import controller and import _init_
Incase of running from the terminal it will only try to import from the current folder. You have to manually add the path of the main folder to this file using the following code at the beging of the file
import sys
sys.path.append("../")
If you want to back 2 folders add ../../ instead of ../
You should not start a submodule of a package directly as a script. This will mess up your hierarchy most of the time. Instead call it as a module:
python -m Core.controller
You can verify the following by adding this to the top of any of your scripts:
import sys
for p in sys.path:
print(repr(p))
The reason the imports work when invoked as:
python main.py
is python will add the directory of the script to the pythonpath (In this case the empty string '')
However, when running
python Core/controller.py
it will add Core to sys.path, rendering the rest of your project unimportable
You can instead use
python -m Core.controller
which'll invoke using runpy and again put the empty string on the python path.
You can read more about invocation options of the python interpreter here: https://docs.python.org/2/using/cmdline.html You can read about runpy here: https://docs.python.org/2/library/runpy.html
I am creating module (with submodules). Lets call it lib. I am trying to make it work as following:
I am able to run it (there is lib.__main__). It uses lib.utils inside.
When executed part of its job is to load other file/module passed by user. Currently it does it by importlib.import_module( name ).
This loaded module also needs to use lib.utils.
I am having following choice:
In loaded module use import utils instead of import lib.utils. I find it somehow misleading and would like to aviod this.
Run module in any external way, even using file with only import lib.__main__ inside.
Only other thing I have tought of was doing sys.path.append(os.getcwd()). Not only it seems very dirty, but also makes log.utils module to load twice.
Is there anything that would allow me to execute lib.__main__, but require using import lib.utils in loaded module?
From the docs
If the script name refers to a directory or zipfile, the script name is added to the start of sys.path and the main.py file in that location is executed as the main module.
In your case, if you run python lib mymodule, lib is added to sys.path and __main__.py is executed. lib is not a package, its simply a directory in sys.path. __main__.py is not in a package and so package-relative imports don't work.
Since lib is in sys.path, its top level .py files can be imported directly and any subdirectories with __init__.py are importable packages. So, both __main__.py and mymodule could do import utils and get the same thing.
Now it gets confusing. Because you are sitting in lib's parent directory and because there is a lib.__init__.py, lib.utils is also valid. Its only that way because of your current directory (or maybe you added the directory to PYTHONPATH or something). So, you've got two different modules as far as python is concerned because you got there on two different paths.
The solution is to delete lib/__init__.py. lib shouldn't be package. Then you have the question of what to do with the modules like lib/utils.py. Normally, one would create a package directory and move the scripts there so that you get namespace encapsulation. Supposing you call that directory mypackages, then __main__.py and mymodule.py could both import mypackages.utils.