-1

I am developing a library in python3x and I'm having some trouble trying to import all modules, classes and functions.

    /example.py
    /math/
        __init__.py
        linalg.py
             solve() #inside module.py

The issue here is that I would like to simply be able to import my library inside example.py and then use all functions defined inside the different modules as numpy does, for example:

import math as m

m.solve()

instead of using

import math as m
m.linalg.solve()

or

import math.linalg as m
m.solve()

How should I define __init__.py to include everything this way. I've tried using dir(linalg), absolute imports, etc by I can't get my head around it.

Thx.

SOLUTION:

At the end what I did was create a wrapping layer inbetween to hide the module dependency.

Inside the __init__.py:

from .linalg import *
from .wrappers import *

then created a wrappers.py along with linalg.py:

from math.linalg import solve

def wrapper_solver():
{
solve()
}

and then in example.py:

import math as m

m.wrapper_solver()

Hope it helps someone.

Gabriel Esp
  • 47
  • 1
  • 10

3 Answers3

2

Two solutions :

  1. Either import the whole path to your linalg.py :

example.py :

#!/usr/bin/env python3                                                         

import math.linalg as m # rather than just `import math`.

m.solve()
  1. Either make solve available directly from math with your __init__.py :

math/__init__.py :

from linalg import solve

Edit :

You could modify your python path as Muhammed Ajwahir suggested. But in my humble opinion that doesn't solve the problem. It's a matter of import path. The root directory is added by default to the Python path (when executing ./example.py). That's enough to import everything in sub directories. I think there is no need to modify the path.

Edit 2:

If you want to import everything in your __init__.py you can also use from math import * (which is considered as a bad practice). Or add everything by hand in your __init__.py.

But in your case you might consider refactoring your tree in just :

.
|-- example.py
|-- math.py

And forget the math directory structure. This way a simple import math should be enough.

I'd also like to point out that math is already an existing library in Python. I think you should consider renaming it to avoid name conflict.

vmonteco
  • 14,136
  • 15
  • 55
  • 86
  • Yes, I have tried both and I'm leaning towards the second but the list of functions in the \__init__.py would be huge – Gabriel Esp Feb 06 '19 at 11:42
  • The problem is that I'd like to call the library from several files and putting them all wouldn't be possible, and adding them all by hand doesn't seem like a good practice either (that's why I mentioned the dir() command to try to do it automatically). Also the names are made up ^^ – Gabriel Esp Feb 06 '19 at 11:54
  • 2
    @GabrielEsp I think the best solution is still to import things explicitly in your `__init__.py`. Maybe you don't need to import everything but only the most used functions and functions you need outside o your math package. For most common functions -> import in `__init__.py`. For any other function/class/item, use the full path in your python import. – vmonteco Feb 06 '19 at 12:04
0

In your linalg.py write __ all __ write all the function you want to expose to the package.
example __ all __ =['solve']

Then in __ init __.py ( module where linalg.py file is present ) file write from .linalg import * this will import all function defined in __ all __ (note function name should be unique) . and then in __ init __.py write __ all __ = linalg.__ all __ ( use + if there are more file ie __ all __ = linalg.__ all __ +file2.__ all __ .

and then in the example, you can call solve as from math import solve.

sahasrara62
  • 10,069
  • 3
  • 29
  • 44
-1

If you want to add something inside a folder you have to add that folder in the system directory. you can do that by -

import sys
sys.path.insert(0, '/path/to/math/folder')

import linalg as m

m.solve()

EDIT 1:

OR

In __init__.py, add

__all__ = ["linalg", "foo", "barr"]

etc, and import math as m in your main script hope that helps.

  • No, but I want to import the whole package. Imagine I have not only linalg, but several other modules. The goal would be to import the whole package and call all functions from the package import. – Gabriel Esp Feb 06 '19 at 11:40
  • In that case in your init.py you have to add - ` __all __ = ["linalg", "foo", "barr"] ` etc, and ` import math as m ` in your main script. – Muhammed Ajwahir Feb 06 '19 at 11:44
  • 1
    I don't think that solves the problem. It's a matter of import path. The root directory is added by default to the Python path (when executing `./example.py`). That's enough to import everything in subdirectories. I think there is no need to modify the path. – vmonteco Feb 06 '19 at 11:59
  • I have done that but I get AttributeError: module 'math' has not attribute 'linalg' – Gabriel Esp Feb 06 '19 at 12:00
  • How did you access the function ? If you import math as m, then you access the function name func() inside the linalg as m.linalg.func() – Muhammed Ajwahir Feb 06 '19 at 12:10
  • Yes, but in the description of the problem I explain that my goal is to access the function only using m.func() – Gabriel Esp Feb 06 '19 at 19:29