Manually importing gtk fails: module not found - python

So I would like to execute a python script from command line then and again, and it has to be very quick. Imports in python are slow because the entire sys.path is searched for the respective modules.
Thus, my idea was to replace
import sys
import gdk.gtk
with
import sys
import imp
imp.load_source("gtk.gdk", "/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/__init__.py")
(I got that path from os.path.abspath(gtk.__file__)
However, python tells me this is invalid: module 'gtk' not found. But isn't this exactly what I am trying to import here?
what am I doing wrong? or
would there be a better way to achieve a direct import?
(error messages in detail below)
/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/__init__.py:23:
RuntimeWarning: Parent module 'gtk' not found while handling absolute import
import sys
/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/__init__.py:30:
RuntimeWarning: Parent module 'gtk' not found while handling absolute import
import gobject as _gobject
/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/__init__.py:40:
RuntimeWarning: Parent module 'gtk' not found while handling absolute import
from gtk import _gtk

Importing the compiled __init__.pyc seems to work here, using import_module instead of import_source. However, the import is still notably slow...
# done manually once
file,filename,descr=imp.find_module('gtk')
print file,filename,descr
script:
# script
gtk=imp.load_module('gtk',FILE,FILENAME,DESCRIPTION) # the respective values
# gtk=imp.load_module("gtk",None,"/usr/lib/python2.7/dist-packages/gtk-2.0/gtk",('','',5))
from gtk import gdk

Related

How can I tell which module/script has just run this script in Python?

I have a module called detector.py, and I want to import the module Vimba into it only if detector.py is being imported by experiment.py. Is this importer-specific conditional importing possible?
If I import this module (detector.py) into a different module, say test.py, I don't want to try to import Vimba.
I've tried checking __name__ to see if it tells me who my importer is, but I only get the general module path of this module project.detection.detector.
You can use sys.modules to check if a module has been imported.
import sys
if 'experiment' in sys.modules:
import Vimba

python relative import: module not found

|Project
|--m1Folder
|--|--__init__.py
|--|--m1.py
|--m2Folder
|--|--__init__.py
|--|--m3Folder
|--|--|--__init__.py
|--|--|--m3.py
m1Folder and m2Folder are inside of Project. m3Folder is inside of m2Folder. All m*Folder contains empty __init__.py.
How to import m1.py, from m3.py file?
I tried from m1Folder import m1 as mo inside m3.py file and gave ModuleNotFoundError: No module named 'm1Folder'. However, pylint in vscode did not show any error.
from ...m1Folder import m1 as mo gives ValueError: attempted relative import beyond top-level package
You can do it by changing the system path with the sys module.
import sys
sys.path.insert(1, '/path/to/application/app/folder')
import m1

Are there reasons to import subpackage or submodules without naming them instead of just importing the parent?

In Python 3, is there a difference between
import os.path
os.path.join(a,b)
and
import os
os.path.join(a,b)
except that the latter is shorter?
(I know about import os.path as path but I'm talking only about the unnamed import form. I found it in some code and was wondering why it was used)
If a package does not include a module in its __init__.py, then
package.module
will not work even if you have already imported pacakge unless you also do
import package.module
This does not apply to package=os and module=path (os is actually a module (contained in os.py) that imports another module, path somewhere in its code)

Python package seems to be incorrectly imported as a module

I'm importing a package of mine called shared in a Django site. This package is an installed app, but when I'm trying to use it accessing its models module then the following exception is thrown:
AttributeError: 'module' object has no attribute 'models'
I'm getting crazy with this! The rest of packages are imported in the same way and aren't causing any problems. This package has the __init__.py.
For example, in the simplest case it fails with the same error too:
import shared
print shared.models
If I use from shared.models import Foo it works, but I'm trying to do this to avoid circular dependencies.
Does anybody have any ideas on this?
The problem is that import shared doesn't import child modules, but from shared.models import FOO does import all of the parent modules. You can import models in your __init__.py so that it comes in with import shared or you can specifically import shared.models after import shared.
shared/__init__.py:
import models
import shared
print shared.models.FOO
or
import shared
import shared.models
print shared.models.FOO

trying to import a *.pyc as a module

I have a python script that is trying to import another script somewhere in the file-system (path is only known at runtime).
To my understanding I need to use the imp module and this might work, but when loading the module I get an error that modules used by the imported module are not found.
Heres the code:
importer.py:
import imp
imp.load_compiled("my_module","full_path_to_my_module\\my_module.pyc")
my_module.py:
import sys
import another_module
When I run importer.py I get htis error message:
ImportError: No module named another_module
Whats going wrong here ?
I suspect that when 'importer.py' is loading 'my_module.pyc' hes also trying to load 'another_module' (thats good) but is looking in the wrong place (eg not 'full_path_to_my_module')
EDIT:
I tried adding 'full_path_to_my_module' to the system path:
import imp
import sys
sys.path.append(full_path_to_my_module)
imp.load_compiled("my_module",full_path_to_my_module+my_module)
But I still get the same error
Maybe I do something thats not necessary - Here's my goal:
I want to be able to use all functionality of 'my_module.pyc' inside 'importer.py'. But the location of 'my_module.pyc' is given as a parameter to 'importer.py'.
imp.load_compiled returns the compiled module object, it is different to the import statement which also binds the module to a name
import imp
my_module = imp.load_compiled("my_module", "full_path_to_my_module/my_module.pyc")
Then you can do something like:
my_module.yayfunctions('a')
Complete example session:
$ cat /tmp/my_module.py
def yayfunctions(a):
print a
$ python -m compileall /tmp/my_module.py
$ ls /tmp/my_module.py*
my_module.py my_module.pyc
$ python
>>> import imp
>>> my_module = imp.load_compiled("my_module", "/tmp/my_module.pyc")
>>> my_module.yayfunctions('a')
a
Edit regarding comment (ImportError: No module named another_module), I assume the error is caused by the code in my_module.pyc, and the another_module.py lives in the same directory
In that case, as others have suggested, it's simpler to just add the directory containing my_module to sys.path and use the regular import mechanism, specifically __import__
Here's a function which should do what you want:
import os
def load_path(filepath):
"""Given a path like /path/to/my_module.pyc (or .py) imports the
module and returns it
"""
path, fname = os.path.split(filepath)
modulename, _ = os.path.splitext(fname)
if path not in sys.path:
sys.path.insert(0, path)
return __import__(modulename)
if __name__ == '__main__':
# Example usage
my_module = load_path('/tmp/my_module.py')
my_module.yayfunctions('test')
It is since at the scope of import another_module your "full_path_to_my_module" isn't known.
Have you tried to add the path to known paths instead, i.e.:
import sys
sys.path.append("full_path_to_my_module")
You don't actually need to use the imp module to load pyc modules.
An easy way to try it out is to make two python modules, one importing from the other and run it. Delete then the imported .py file so you only get the .pyc file left: when running the script the import will work just fine.
But, for importing py files from random directories, you may want to add that directory to the python path first before importing it.
For instance:
import sys
sys.path.insert(0, "/home/user/myrandomdirectory")
Loading pyc files works the exact same way as loading a py file except it doesn't do a compile step. Thus just using import mymodule will work as long as the version number of the pyc is the same as the python you're running. Otherwise you'll get a magic number error.
If you module isn't in your path you'll need to add that to sys -- or if its a subdirectory, add a __init__.py file to that directory..

Categories