My directory structure is:
package_name/
__init__.py
script.py
time.py
I'm trying to import time (the built-in package) from script.py. however, my sibling time.py is hooked up instead.
What's the syntax of importing a package globally? (e.g. importing from /usr/lib/python2.7/dist-packages)
In c# i know it as the global:: prefix, what's the equivalent in python?
Be more explicit with your imports.
import time will import the python time module.
from mypackage import time will import the time module in your mypackage package.
import time should never import mypackage.time
That said, don't shadow python built-in names, it's a bad habit and leads to these headaches later.
A Hack
While there are other ways, i adopted this one
1) add a sub package
Let's call it utils. your directory tree should look like:
package_name/
__init__.py
script.py
time.py
utils/
__init__.py
2) create a file named builtin.py under that package
This should be the contents of builtin.py :
import time
time = time
3) use it!
Import time in script.py using this:
from utils.builtin import time
time.sleep(5)
Related
I have a python package defined via __init__.py in a folder named python_utils that has many python scripts in it.
python_utils/
__init__.py
print_pretty.py
script_1.py
...
For convenience this __init__.py imports all of them using:
from .pretty_print import pretty_print
from .scritp_1 import func1
from .script_2 import func2
....
The problem I have is that some of the python scripts depend on packages that may not be available at run time. So when I try to import a very trivial function from the package (from python_utils import print_pretty), it fails because of the dependencies the other scripts have. I also tried to import directly with from python_utils.print_pretty import print_pretty same problem. I can get rid of the __init__.py to solve the problem, but it saves me a lot of typing when importing packages. Is there a way I can import only pretty_print without getting the dependencies from the other scripts?
I want to use relative import in Python 3.
My project:
main_folder
- __init__.py
- run.py
- tools.py
I want to have in run.py (MyClass declared in __init__.py):
from . import MyClass
And in run.py:
from .tools import my_func
An ImportError is raise.
Alternatively, with absolute import, debugging in PyCharm does not work and the library takes from installed packages, not my directory.
I know one way, but it is terrible:
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
How to use this import in my project?
When you use PyCharm, it automatically makes the current module main, so relative statements like from . import <module> will not work. read more here.
to fix your problem, put the __init__.py and tools.py files in a sub-directory
main_directory/
run.py
sub_directory/
__init__.py
tools.py
in your run.py file, write the following as your import statements
from sub_directory import tools
from sub_directory.__init__ import MyClass
Edit: as #9000 mentioned, you can write from sub_directory import MyClass and achieve the same thing.
Say my project is structured like this:
myproject
├── calendar.py
├── foo.py
└── __init__.py
In foo.py, I have
from calendar import isleap
I thought in Python 3.x, without using the explicit .calendar the code above should load the build-in calendar module instead my own calendar module, but apparently my local calendar.py is still being imported and it throws an error because there's no 'isleap' in mypkg/calendar.py. Why was my local calendar module imported here?
I had to rename calendar.py to cal.py to get this work..
from __future__ import absolute_import is the default on Python 3. Therefore from calendar import isleap statement imports the top-level module calendar.
If you see other results; it means either you are not using Python 3 or you are trying to run a python module from inside a package as a script (myproject directory itself is in sys.path). If the latter then your calendar.py becomes the top-level module and (due to the current directory comes before stdlib directories in sys.path) from calendar import isleap imports calendar.py from the current directory. "Never add a package directory, or any directory inside a package, directly to the Python path"
To avoid it, do not run modules from within python packages directly e.g., do not do this: cd myproject; python foo.py. Do this instead: python -mmyproject.foo (or you could define what scripts should be run in setup.py or create a similar script manually: from myproject import foo; foo.main()).
If you want to run a Python package as a script then create myproject/__main__.py then run python -mmyproject.
If you want to do a relative import in Python 3; do it explicitly e.g., in myproject/foo.py:
from .calendar import something
Or do an absolute import:
from myproject.calendar import something
It looks like your path or directory structure is set up wrong.
Given the following structure the full name of your calendar module should be myproject.calendar. You can check this by printing out the __name__ attribute of your module. For this to be the case, the path that your program uses to import local modules must be the folder containing myproject.
myproject
├── calendar.py
├── foo.py
└── __init__.py
It seems like the path you are using is actually myproject. Meaning calendar.py is turned into the root level module calendar, rather than myproject.calendar. Python prefers local modules to builtin ones, and so imports your calendar module.
More typically you might do something like this.
MyProjectFolder
├── main.py
└── myproject
├── calendar.py
├── foo.py
└── __init__.py
And then run your program like this:
#! /bin/bash
cd /path/to/MyProjectFolder
python main.py
Python will check your local modules and load them firstly by import.
from calendar import isleap will search the module calendar in your locale package firstly. If not found, it will import from the builtin library calendar.
from .calendar import isleap will only import from your locale module calendar. If not found, raises a exception ImportError.
That is why you should use relative import in a package.
You can do a trick like that to import the builtin library without checking of the local modules. But it's only a trick. I will never use it in production. You should better rename your module calendar.
import imp, sys
f, pathname, desc = imp.find_module("calendar", sys.path[1:])
calendar = imp.load_module("calendar", f, pathname, desc)
f.close()
from calendar import isleap
I recently decided to upgrade to python 3, and start converting some of my scripts. I encountered a problem in a script that uses a module named io - in python 2, this is perfectly fine, however in python 3, io is a standard module for files. I found this old question about the same kind of problem, however this appears to be in reference to python 2. I have the opposite problem - given two files, main.py and io.py in the top level package, import io in main.py will import the standard io module, not the local one. from __future__ import absolute_imports didn't help, and from . import io and related attempts fail as expected (which I have never understood - python really doesn't know where the top level package is?). Renaming is obviously a solution, but if possible I'd like to avoid it. Is there some python 3 standard way of resolving module name conflicts?
Here's my answer:-
My directory structure:-
calvin$ tree /Users/calvin/work/learn3/
/Users/calvin/work/learn3/
└── myspecialpackage
├── __init__.py
├── __init__.pyc
├── io.py
├── io.pyc
└── main.py
__init__.py is an empty file.
io.py is your custom module which conflicts with python3's io module.
main.py contains this bunch of example code:-
import os
import sys
# These two lines are not needed you are installing the `myspecialpackage` via pip/pypi and as setup.py script places "myspecialpackage" and all its contents in your python site-packages, which is already in PYTHONPATH.
our_package_root = os.path.dirname(os.path.realpath(__file__))
sys.path.append(our_package_root)
from myspecialpackage import io
print(io.__file__)
And the imported io module will be the one in your io.py and not python3's module.
As a bonus, using this methodology will allow us to have your custom io.py as well as python3's io module (if you so desire having your cake and eat it ;-)). You can deconflict the use of the namespace io like this:-
from myspecialpackage import io as my_special_io
print(my_special_io.__file__)
import io
print(io.__file__)
Running main.py will then give you:-
In [3]: run myspecialpackage/main.py
/Users/calvin/work/learn3/myspecialpackage
./myspecialpackage/io.py
/Users/calvin/.virtualenvs/learn3/bin/../lib/python3.3/io.py
Take note of the comment I made above regarding
our_package_root = os.path.dirname(os.path.realpath(__file__))
sys.path.append(our_package_root)
First off all: I'm sorry, I know there has been lots of question about relative imports, but I just didn't find a solution. If possible I would like to use the following directory layout:
myClass/
__init__.py
test/
demo.py
benchmark.py
specs.py
src/
__init__.py
myClass.py
Now my questions are:
How do the test files from within the package properly import myClass.py?
How would you import the package from outside, assuming you take myClass as submodule in libs/myClass or include/myClass?
So far I couldn't find an elegant solution for this. From what I understand Guido's Decision it should be possible to do from ..src import myClass but this will error:
ValueError: Attempted relative import in non-package
Which looks as it doesn't treat myClass as packages. Reading the docs:
The __init__.py files are required to make Python treat the directories as containing packages;
It seems I'm missing something that specifies where the scripts of the package are, should I use .pth ?
ValueError: Attempted relative import in non-package
Means you attempt to use relative import in the module which is not package. Its problem with the file which has this from ... import statement, and not the file which you are trying to import.
So if you are doing relative imports in your tests, for example, you should make your tests to be part of your package. This means
Adding __init__.py to test/
Running them from some outside script, like nosetests
If you run something as python myClass/test/demo.py, relative imports will not work too since you are running demo module not as package. Relative imports require that the module which uses them is being imported itself either as package module, from myClass.test.demo import blabla, or with relative import.
After hours of searching last night I found the answer to relative imports in python!! Or an easy solution at the very least. The best way to fix this is to have the modules called from another module. So say you want demo.py to import myClass.py. In the myClass folder at the root of the sub-packages they need to have a file that calls the other two. From what I gather the working directory is always considered __main__ so if you test the import from demo.py with the demo.py script, you will receive that error. To illustrate:
Folder hierarchy:
myClass/
main.py #arbitrary name, can be anything
test/
__init__.py
demo.py
src/
__init__.py
myClass.py
myClass.py:
def randomMaths(x):
a = x * 2
y = x * a
return y
demo.py:
from ..src import myClass
def printer():
print(myClass.randomMaths(42))
main.py:
import test.demo
demo.printer()
If you run demo.py in the interpreter, you will generate an error, but running main.py will not. It's a little convoluted, but it works :D
Intra-package-references describes how to myClass from test/*. To import the package from outside, you should add its path to PYTHONPATH environment variable before running the importer application, or to sys.path list in the code before importing it.
Why from ..src import myClass fails: probably, src is not a python package, you cannot import from there. You should add it to python path as described above.