The problem
My Python-2.7 project needs to use two third-party modules, let's call them firstmodule and secondmodule.
There are two different submodules with the same name, say thesubmodule, one in firstmodule and one in secondmodule.
There is another third party module, let's call it mainmodule, which means to import firstmodule.thesubmodule.
But when it tries to import thesubmodule, it ends up importing it from secondmodule, and everything fails because these two submodules have the same name but they are completely different.
I think it would not be nice to modify the implementation of mainmodulejust to avoid this ambiguity, as it is a third party module and I should just use it without modifying it.
The code
In terms, of code, when I write the following in my project:
import mainmodule
then mainmodule tries to execute this:
import thesubmodule
but it ends up importing secondmodule.thesubmodule instead of firstmodule.thesubmodule, then it generates errors like this:
NameError: name 'blabla' is not defined
(where 'blabla' can only be found in firstmodule.thesubmodule).
The question
Is there a way to specify, when importing mainmodule, that any reference to thesubmodule refers to firstmodule.thesubmodule ?
Further observations
When I try to remove the path of secondmodule from PYTHONPATH then thesubmodule is correctly imported, but I need secondmodule in my project, so not importing it is not an option unfortunately.
If it was possible to set a specific value for PYTHONPATH just for that single import, and then restore its original value afterwards, then I guess it would work, but it does not seem an easy thing to do.
A "dirty" attempt?
Based on my last observation, would it be too dirty to temporarily change the value of PYTHONPATH with a shell command just before importing mainmodule? I mean something like:
...
import os
...
savePYTHONPATHvalue()
os.system('export PYTHONPATH=somevalue')
import mainmodule
restorePYTHONPATHvalue()
...
Related
I've got a Python script.
I've had several functions in this script which I decided to move to a 'package' folder beside the main script.
In this folder, I created a *.py file where I put all my functions.
I've placed an empty init.py near this file within the 'package' folder.
When starting the code of my main script with:
from package_folder.my_functions import *
the script works well when calling every functions from that file.
But when trying to import it directly:
import package_folder.my_functions
it doesn't seems to work as well as with the above technique.
The cause seems to be the fact that in the file wellmy_functions.py, I have a function that needs an other one, declared previously in that file.
I had this obscure error on that function that needs an other one:
TypeError: 'NoneType' object is not callable
Is this permissible and if not, how to manage this case?
It's generally not a good idea to use from module import *. Wildcard importing leads to namespace pollution; you imported more names than you need and if you accidentally refer to an imported name you may not get the NameError you wanted.
Also, if a future version of the library added additional names, you could end up masking other names, leading to strange bugs still:
Example
from my_mod1 import func1
from my_mod2 import *
If you upgrade my_mod2 and it now includes a my_mod2.func1 it'll replace the my_mod1.func1 import in the 1st line.
In Python 2.7, I'm getting
'module' has no attribute
, and/or
'name' is not defined
errors when I try to split up a large python file.
(I have already read similar posts and the Python modules documentation)
Say you have a python file that is structured like this:
<imports>
<50 global variables defined>
<100 lengthy functions that each use most or all of the globals
defined above, and also call each other>
<main() that calls some of the functions and uses the globals>
So I can easily categorize groups of functions together, create a python file for each group, and put them there. The problem is whenever I try to call any of them from the main python file, I get the errors listed above. I think the problem is related to circular dependencies. Since all of the functions rely on the globals, and each other, they are circularly dependent.
If I have main_file.py, group_of_functions_1.py, and group_of_functions_2.py,
main_file.py will have:
import group_of_functions_1.py
import group_of_functions_2.py
and group_of_functions_1.py will have
import main_file.py
import group_of_functions_2.py
and group_of_functions_2.py will have
import main_file.py
import group_of_functions_1.py
Regardless of whether I use "import package_x" or "from package_x import *" the problem remains.
If I take the route of getting rid of the globals, then most of the functions will have 50 parameters they will be passing around which then also need to be returned
What is the right way to clean this up?
(I have already read similar posts and the Python modules documentation)
One of the sources of your errors is likely the following:
import group_of_functions_1.py
import group_of_functions_2.py
When importing, you don't add .py to the end of the module name. Do this instead:
import group_of_functions_1
import group_of_functions_2
I have ran into strange problem, which I cannot find an answer.
I want to use file which may be located in different modules, with same path names (folders contain empty init.py files as well):
road1/pato/
road2/pato/modtest.py
where modtest contains simply a=1
Simple script for testing, test.py , contains:
import pato.modtest
print(pato.modtest.a)
and running
PYTHONPATH=road2/ python test.py
runs fine as expected. What is confusing, is that
PYTHONPATH=road1/:road2/ python test.py
gives an error
ImportError: No module named 'pato.modtest'
All the documentation I have read states that PYTHONPATH may contain multiple path-s and it should be just fine, running program is just looking through them in order. In this case, however, adding empty path in the front of path seem to prevent reading from later path's. If this is expected behaviour, fine, I'd appreciate links to good docs about it.
You have a namespace clash.
According to your PYTHONOPATH, when you import "pato.modtest" Python first looks if "pato" or "pato.modtest" are present in the current namespace.
As they are not present it then goes to sys.path and tries the first path which in your case is "road1/".
It finds the module "pato" there and then looks for object "modtest", not having found, it looks for a module road1/pato/modtest, not having found, it gives up.
I have two codefiles in python, let's say mainfile.py and separatecode.py. I would like to run separatecode.py from within mainfile.py, referencing the specific directory where separatecode.py is stored.
So the pseudocode of what I am looking to do would be something like:
import C:\Users\Jack\Documents\MyFolder\separatecode.py
A number of questions discuss importing, but I can't find one that discusses importing a specific file you wrote in a particular directory. I would like to be able to use functions defined in separatecode.py and am looking for the equivalent of the source("separatecode.r") command in R if that helps.
Add that directory to your sys.path by doing:
import sys
sys.path.append('/directory/to/my/file')
Import the module as normal:
import separatecode
The code you used will not work. It will give a syntax error.
Look at the documentation for the import statement, especially the grammar. A module is one or more identifiers separated by dots.
You can make import separatecode work by adding C:\Users\Jack\Documents\MyFolder to the PYTHONPATH environment variable. This will make it available to all Python scripts. Or you can add that path to sys.path in mainfile.py before importing separatecode.
Try something like this:
import imp
foo = imp.load_source('Module_name', 'Path\To\module.py')
foo.MyClass()
you dont need the foo.MyClass() it was just an example to show that the module works like any other module
no you can import a module from anywhere using the path and its name and you can acsess all its functions etc
for anything else check out:
Python Imp
I hope this is what you were looking for
I am importing a lot of different scripts, so at the top of my file it gets cluttered with import statements, i.e.:
from somewhere.fileA import ...
from somewhere.fileB import ...
from somewhere.fileC import ...
...
Is there a way to move all of these somewhere else and then all I have to do is import that file instead so it's just one clean import?
I strongly advise against what you want to do. You are doing the global include file mistake again. Although only one module is importing all your modules (as opposed to all modules importing the global one), the remaining point is that if there's a valid reason for all those modules to be collected under a common name, fine. If there's no reason, then they should be kept as separate includes. The reason is documentation. If I open your file, and see only one import, I don't get any information about what is imported and where it comes from. If on the other hand, I have the list of imports, I know at a glance what is needed and what not.
Also, there's another important error I assume you are doing. When you say
from somewhere.fileA import ...
from somewhere.fileB import ...
from somewhere.fileC import ...
I assume you are importing, for example, a class, like this
from somewhere.fileA import MyClass
this is wrong. This alternative solution is much better
from somewhere import fileA
<later>
a=fileA.MyClass()
Why? two reasons: first, namespacing. If you have two modules having a class named MyClass, you would have a clash. Second, documentation. Suppose you use the first option, and I find in your code the following line
a=MyClass()
now I have no idea where this MyClass comes from, and I will have to grep around all your files in order to find it. Having it qualified with the module name allows me to immediately understand where it comes from, and immediately find, via a /search, where stuff coming from the fileA module is used in your program.
Final note: when you say "fileA" you are doing a mistake. There are modules (or packages), not files. Modules map to files, and packages map to directories, but they may also map to egg files, and you may even create a module having no file at all. This is naming of concepts, and it's a lateral issue.
Of course there is; just create a file called myimports.py in the same directory where your main file is and put your imports there. Then you can simply use from myimports import * in your main script.