Python import directory path

Import python package from local directory into interpreter

I’m developing/testing a package in my local directory. I want to import it in the interpreter (v2.5), but sys.path does not include the current directory. Right now I type in sys.path.insert(0,’.’) . Is there a better way? Also,

ValueError: Attempted relative import in non-package 

Your problem is probably different, but my problem was just that I left the «.py» extension on it after the import statement, which causes it to fail with the error «ModuleNotFoundError: No module named ‘myFile.py’; ‘myFile’ is not a package». Also, the cwd is not explicitly in my sys.path for Python 3.8.10 shell run from terminal either, though it is in the Python 3.8.10 IDLE shell, and in both cases an empty string is.

10 Answers 10

You can use relative imports only from in a module that was in turn imported as part of a package — your script or interactive interpreter wasn’t, so of course from . import (which means «import from the same package I got imported from») doesn’t work. import mypackage will be fine once you ensure the parent directory of mypackage is in sys.path (how you managed to get your current directory away from sys.path I don’t know — do you have something strange in site.py, or. )

To get your current directory back into sys.path there is in fact no better way than putting it there.

Читайте также:  Yandex translator api python

Python 2.5 for Ubuntu 8.10 does not have the current directory (empty string) in sys.path for the interpreter. I didn’t change anything, so it somehow got shipped that way. I just installed 3.0 and sys.path DOES have » in sys.path.

@projectshave, OK, Ubuntu’s no doubt got their reasons! I haven’t noticed that in 8.04 (what we currently use at work) but maybe I just wasn’t paying enough attention.

I am partially wrong. Python invoked from a shell has the current directory in sys.path. Python invoked from Emacs does not have the current directory. Strange.

Ah well, then it’s Emacs who’s got their reasons as opposed to Ubuntu’s (as a vim user I don’t really know;-). You can conditionally insert ‘.’ in your sys.path iff not there of course.

@Alex Martelli: Thank you so much! I’ve been searching and searching for the solution to why my add-on (for Anki) needed a different import statement when being run ‘locally’ as a script. When I instead added a local_launch() method and imported/launched the whole thing from a script outside the package folder, it worked like a charm!

See the documentation for sys.path:

If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first.

So, there’s no need to monkey with sys.path if you’re starting the python interpreter from the directory containing your module.

Also, to import your package, just do:

Since the directory containing the package is already in sys.path, it should work fine.

@JAR.JAR.beans the current working directory should be the first thing in sys.path so files there should be found before files anywhere else in the working environment.

Good point. That is, if we run the file from the local directory. In the case it’s some other folder, and in the case a change to sys.path is needed — it means sys.path.insert(0, new_path) rather than sys.path.append(new_path) .

 try: from . import mymodule # "myapp" case except: import mymodule # "__main__" case 

I like this solution, it is the most simple. The only remaining question is why did the «only one way to do it» rule has been deemed optional when implementing imports . Seriously there is about 15 ways to declare and organize the packages, all of which have drawbacks

using an exception for other purposes than raising an exception is a bad coding style, this should be avoided at any cost

@LPVOID catching exceptions is common practice in python. It is not bad coding style (although except: ImportError might be better style in this case).

@ForeverWintr yeah, I guess this approach is popular amongst python devs because python is a dynamically typed language, and it is much quicker to use exception than analyzing the type of a variable. But this all doesn’t make it an innocent approach, IMHO it is just a lazy and bad coding style.

Naahh, ForeverWintr is quite right here. This is common practice. Atleast for the case of local imports, even static code checkers like mypy can get away with it. — And by the way, in production code I used to catch ImportError although it may be better to switch to ModuleNotFoundError. The mere existance of that exception class (in python 3.6) points to the fact that people were catching import-errors for a long time. @lpvoid

If you want to run an unmodified python script so it imports libraries from a specific local directory you can set the PYTHONPATH environment variable — e.g. in bash:

export PYTHONPATH=/home/user/my_libs python myscript.py 

If you just want it to import from the current working directory use the . notation:

export PYTHONPATH=. python myscript.py 

Exporting PYTHONPATH includes programming outside python (e.g. in bash). Additionally, in docs.python.org/3/using/cmdline.html is clearly stated that «default search path is installation dependent«.

Inside a package if there is setup.py, then better to install it

A simple way to make it work is to run your script from the parent directory using python’s -m flag, e.g. python -m packagename.scriptname . Obviously in this situation you need an __init__.py file to turn your directory into a package.

A bit late to the party, but this is what worked for me:

>>> import sys >>> sys.path.insert(0, '') 

Apparently, if there is an empty string, Python knows that it should look in the current directory. I did not have the empty string in sys.path , which caused this error.

Using sys.path should include current directory already.

however it may be not a good practice, so why not just use:

Problem with is that it will load the package from the global python env, it might load the package/file from the local folder, but it could just as well load some other random mypackge that is in the working env.

Speaking for python3.. I wanted to use an improved version of a library that’s installed in my environment. There are some extra print statements it makes to show that it and not the original lib is being used.

I placed the lib’s folder next to the python script. Ran the script.. it ran with the local lib with the modifications.

Removed the folder and ran it again — this time it ran with the installed lib.

So, solution was simple : place the lib’s folder (with same name as in your import statement) in your project folder. That does the job, at least at my end.

This is on a standard Linux Mint 20.04 system, with a python 3.8 virutal environment activated (so «(py3.8)» appears in my terminal when I’m in the virtual env)

Источник

Import a module from a relative path

How do I import a Python module given its relative path? For example, if dirFoo contains Foo.py and dirBar , and dirBar contains Bar.py , how do I import Bar.py into Foo.py ? Here’s a visual representation:

dirFoo\ Foo.py dirBar\ Bar.py 

Check my answer, it is the most complete so far, others are not working in special case, for example when you call the script from another directory or from another python script. See stackoverflow.com/questions/279237/…

Just in case somebody wants to do it statically and gets here (like I did 🙂 you can also set up the PYTHONPATH environment variable

22 Answers 22

Assuming that both your directories are real Python packages (do have the __init__.py file inside them), here is a safe solution for inclusion of modules relatively to the location of the script.

I assume that you want to do this, because you need to include a set of modules with your script. I use this in production in several products and works in many special scenarios like: scripts called from another directory or executed with python execute instead of opening a new interpreter.

 import os, sys, inspect # realpath() will make your script run, even if you symlink it :) cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0])) if cmd_folder not in sys.path: sys.path.insert(0, cmd_folder) # Use this if you want to include modules from a subfolder cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder"))) if cmd_subfolder not in sys.path: sys.path.insert(0, cmd_subfolder) # Info: # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ . # __file__ fails if the script is called in different ways on Windows. # __file__ fails if someone does os.chdir() before. # sys.argv[0] also fails, because it doesn't not always contains the path. 

As a bonus, this approach does let you force Python to use your module instead of the ones installed on the system.

Warning! I don’t really know what is happening when current module is inside an egg file. It probably fails too.

Источник

How to get current import paths in Python?

I get an ImportError exception somewhere in the code, but the same module can be imported safely at startup of the application. I’m curious to see which paths Python looks for modules to import, so that I can trace why this problem occurs. I found this: print sys.path Is this the list of ALL paths that system looks when tries to import a module?

4 Answers 4

The path locations that python checks by default can be inspected by checking sys.path .

Yes, it is. More details in Python Standard Library Modules documentation at docs.python.org/tutorial/modules.html#the-module-search-path

If you want a bit better formatting:

import sys from pprint import pprint pprint(sys.path) 

The other answers are almost correct

import sys import_paths = sys.path 
import sys import os import copy import_paths = copy.copy(sys.path) if '__file__' in vars(): import_paths.append(os.path.abspath(os.path.join(__file__,'..'))) 

In both versions the main file (i.e. __name__ == ‘__main’ is True ) automatically adds its own directory to sys.path. However Python 3 only imports modules from sys.path . Python 2.7 imports modules from both sys.path AND from the directory of the current file. This is relevant when you have a file structure like:

|-- start.py |-- first_import | |-- __init__.py | |-- second_import.py 

with contents
start.py:
import first_import
__init__.py:
import second_import.py

In Python 3 directly running __init__.py will work, but when you run start.py, __init__.py wont be able to import second_import.py because it wont be in sys.path .

In Python 2.7 when you run start.py, __init__.py will be able to import second_import.py even though its not in sys.path since it is in the same folder as it.

I cant think of a way to perfectly duplicate Python 2.7’s behavior in Python 3 unfortunately.

Источник

Оцените статью