I'm brand new at python package management, and surely have done something wrong. I was encouraged to create a directory structure as follows:
bagoftricks
├── bagoftricks
│ ├── bagoftricks
│ │ ├── __init__.py
│ │ └── bagoftricks.py
│ └── __init__.py
├── README.md
└── setup.py
bagoftricks.py contains two functions, levenshtein()
and geofind()
.
I would like to call these as:
import bagoftricks
x = bagoftricks.levenshtein(arg1,arg2)
Instead, I find I have to do this:
import bagoftricks
x = bagoftricks.bagoftricks.levenshtein(arg1,arg2)
Is there a better way to organize my packages in the first place, without the naming redundancy?
UPDATE
So, I followed Avichal Badaya's instructions below, and removed one level of nesting. That is, I now have...
bagoftricks
├── bagoftricks
│ ├── __init__.py
│ └── bagoftricks.py
├── README.md
└── setup.py
However, to call this package, I still have...
from bagoftricks.bagoftricks import geofind()
or
import bagoftricks
then
>>> bagoftricks.bagoftricks.geofind()
Rather than the desired....
from bagoftricks import geofind()
or
import bagoftricks
>>> bagoftricks.geofind()
I cannot remove that extra layer of nesting. When I try, by analogy, to remove one more level of nesting, so that my module is flat, as:
bagoftricks
├── __init__.py
├── bagoftricks.py
├── README.md
└── setup.py
I cannot build the package at all...
$ python setup.py build
running build
running build_py
error: package directory 'bagoftricks' does not exist
What's the secret for natural imports like standard packages use, without redundant top-level name imports?
The first level "bagoftricks" is fine. That's just the name of your "project" so to speak. In the you have a setup.py, and other files that tell the packaging systems what they need to know.
You can then have the code directly in this module, or in a src directory. You can even go as far as just having this structure:
bagoftricks
├── bagoftricks.py
├── README.md
└── setup.py
But I would not recommend that, mostly because you might want to reorganize things later, and it's easier if you already have a "proper" package. Also most people, tools and docs assume you have a package, so it's easier.
So the minimum would be:
bagoftricks
├── bagoftricks
│ └── __init__.py
├── README.md
└── setup.py
With __init__.py
containing the functions you want to import. You then use these functions like this:
from bagoftricks import levenshtein, anotherfunction
Once that __init__.py
becomes too big, you want to split it up in several modules, giving you something like this:
bagoftricks
├── bagoftricks
│ ├── __init__.py
│ ├── anothermodule.py
│ └── levenshtein.py
├── README.md
└── setup.py
Your __init__.py
should then import the functions from the various modules:
from bagoftricks.levenshtein import levenshtein
from bagoftricks.anothermodule import anotherfunction
And then you can still use them like like you did before.
Follow following structure :
bagoftricks
── bagoftricks
│ ├── __init__.py
│ └── bagoftricks.py
├── README.md
└── setup.py
and then you should be able to use it as :
from bagoftricks.bagoftricks import levenshtein, geofind
but after you make the change in folder structure do :-
pip uninstall <your package name mostly mentioned in setup.py>
and reinstall the package
meanwhile check your setup.py
#!/bin/env python
import os.path
from setuptools import setup, find_packages
def current_path(file_name):
return os.abspath(os.path.join(__file__, os.path.pardir, file_name))
setup(
name = 'bagoftricks',
version = '0.1',
include_package_data = True,
packages=find_packages(),
)
setup might have some other parameters too. I hope it works for you.
with the updated structure you posted
bagoftricks
├── bagoftricks
│ ├── __init__.py
│ └── bagoftricks.py
├── README.md
└── setup.py
into bagoftricks/__init__.py import all functions that you need
__init__.py
from bagoftricks import geofind, levenshtein
into a different program you can do the follwing
from bagoftricks import geofind
import bagoftricks; bagoftricks.geofind(); bagoftricks.bagoftriks.geofind()
note that you can import as well a wild card
from bagoftricks import *