Problem with importing files into different directories

Asked

Viewed 180 times

1

I’m having a problem using different files in different directories, this is the directory tree of my project:

DeatHash
├── deathash
│   ├── deathash.py
│   ├── dictionaries
│   │   ├── dictionary_test.txt
│   │   └── dictionary.txt
│   ├── files
│   │   ├── archive_test.txt
│   │   ├── cesar.txt
│   │   └── vigenere.txt
│   ├── __init__.py
│   └── __pycache__
│       └── __init__.cpython-36.pyc
├── doc
├── __init__.py
├── LICENSE
└── test
    └── test_deathash.py

I need to access the main module deathash.py, way:

Deathash/deathash/deathash.py

from the module test_deathash.py, way:

Deathash/test/test_deathash.py

I tried to put init.py in the directories(Obs: put with _(underline) before and after 'init', with .py at the end), also tried to use in test_deathash.py, the code

from deathash.deathash import *

Another solution I found is to add to the path the directory that contains the function I will use, but apparently this solution would be ineffective if the project is taken to another directory, which may happen, so if you know of any other solution to the problem please help me.

  • 1

    Already considered the possibility of using virtual env?

  • 1

    @Andersoncarloswoss Yes, I was going to set up a virtual env here for the project, but I thought it would only help in the matter of 'Ibraries' and its versions...

  • Also, but you can use virtual env to install your module, even in development, with the flag --editable PIP and thus be able to import normally in the test files.

  • No - virtualenv is life - I don’t argue in my answer, but it will work better if you have a virtualenv. Without one, your package and others you need will get installed directly in Python’s system.

2 answers

2

Your "deathash" as is a Python "package" (a collection of multiple modules).

As a rule, what Python does to find packages is:

  1. It looks for the package name in the folder it is running in (where you typed "python" in the terminal, or in the folder where the file is ". py" you click, if not by terminal)
  2. In the standard Python library (installed together with the current interpreter, which can be a virtualenv)
  3. In the folder "site-Packages" that is together with the interpreter. In this folder there may also be some special files that point to packages installed in other places - only that these files are complicated, and created by "distutils" or "setuptools" from code that usually stays in a file setup.py in your project.
  4. in any folder that is in the environment variable PYTHONPATH.

After the program is running, all these folders are in order in the list that is shown in the variable sys.path. So, simply placing the folder where the "deathash" folder is manually in the sys.path list will work (with the methods .append or .insert list norms)

But that’s not the most "clean" way to do it - since in that case, your test will depend on finding the main package "alone".

The "most correct" is that your deathash is installed - either in the main Python, or in the current virtualenv - but this requires the creation of an appropriate "setup.py" file.

This is not difficult - a mimio setup.py can have about 10 lines - see documentation here https://setuptools.readthedocs.io/en/latest/setuptools.html#basic-use

Example:

from setuptools import setup, find_packages
setup(
    name="HelloWorld",
    version="0.1",
    packages=find_packages(),
)

For the example of 4 lines of setup.py from the link above to work, you only need to: install the setuptools, escrver your setup.py, and call it with the option "develop": python setup.py develop - this will create a permanent link on the site-Packages of your Python environment to your package, and it will at all times be found.

And finally, the simplest form of all, which requires no changes, run your test script by calling it from the folder where the directories are deathhash and tests (in case the DeatHash): so much so deathash as tests will be visible as packages. (rule "1" above: it looks for the package in the folder Python is running from)

python test/test_deathash.py

Or, if you are using the pytests:

py.test test

0

For those who also have this question, it’s good to know that you did right in putting the files __init__.py in folders. Without this it would not work.

For your specific case, in the file test_deathash.py begin as follows:

import sys
sys.path.append('../deathash/')
from deathash import *

Browser other questions tagged

You are not signed in. Login or sign up in order to post.