Подтвердить что ты не робот

Как структурировать пакеты python без повторения имени верхнего уровня для импорта

Я новичок в управлении пакетами python и, несомненно, сделал что-то не так. Мне было предложено создать структуру каталогов следующим образом:

bagoftricks
├── bagoftricks
│   ├── bagoftricks
│   │   ├── __init__.py
│   │   └── bagoftricks.py
│   └── __init__.py
├── README.md
└── setup.py

bagoftricks.py содержит две функции: levenshtein() и geofind().

Я бы назвал их как:

import bagoftricks

x = bagoftricks.levenshtein(arg1,arg2) 

Вместо этого я считаю, что должен это сделать:

import bagoftricks

x = bagoftricks.bagoftricks.levenshtein(arg1,arg2) 

Есть ли лучший способ организовать мои пакеты в первую очередь без резервирования имен?

UPDATE

Итак, я последовал инструкциям Avichal Badaya ниже и удалил один уровень гнездования. То есть, у меня теперь есть...

bagoftricks
├── bagoftricks
│   ├── __init__.py
│   └── bagoftricks.py
├── README.md
└── setup.py

Однако для вызова этого пакета у меня все еще есть...

from bagoftricks.bagoftricks import geofind()

или

import bagoftricks

затем

>>> bagoftricks.bagoftricks.geofind()

Вместо желаемого....

from bagoftricks import geofind()

или

import bagoftricks

>>> bagoftricks.geofind()

Я не могу удалить этот дополнительный слой вложенности. Когда я попытаюсь, по аналогии, удалить еще один уровень вложенности, чтобы мой модуль был плоским, как:

bagoftricks
├── __init__.py
├── bagoftricks.py
├── README.md
└── setup.py

Я не могу создать пакет вообще...

$ python setup.py build
running build
running build_py
error: package directory 'bagoftricks' does not exist

В чем секрет естественного импорта, например стандартных пакетов, без избыточного импорта имени верхнего уровня?

4b9b3361

Ответ 1

Первый уровень "bagoftricks" в порядке. Это просто название вашего "проекта", так сказать. У вас есть setup.py и другие файлы, которые сообщают упаковочным системам, что им нужно знать.

Затем вы можете получить код непосредственно в этом модуле или в каталоге src. Вы даже можете дойти до такой структуры:

bagoftricks
├── bagoftricks.py
├── README.md
└── setup.py

Но я бы не рекомендовал это, главным образом потому, что вы захотите реорганизовать вещи позже, и это проще, если у вас уже есть "правильный" пакет. Также большинство людей, инструменты и документы предполагают, что у вас есть пакет, так что это проще.

Таким образом, минимум будет:

bagoftricks
├── bagoftricks
│   └── __init__.py
├── README.md
└── setup.py

С __init__.py, содержащим функции, которые вы хотите импортировать. Затем вы используете следующие функции:

from bagoftricks import levenshtein, anotherfunction

Как только этот __init__.py станет слишком большим, вы хотите разбить его на несколько модулей, что даст вам что-то вроде этого:

bagoftricks
├── bagoftricks
│   ├── __init__.py
│   ├── anothermodule.py
│   └── levenshtein.py
├── README.md
└── setup.py

Затем ваш __init__.py должен импортировать функции из различных модулей:

from bagoftricks.levenshtein import levenshtein
from bagoftricks.anothermodule import anotherfunction

И тогда вы все равно можете использовать их, как и раньше.

Ответ 2

Следуйте следующей структуре:

bagoftricks 
    ── bagoftricks
    │ ├── __init__.py
    │ └── bagoftricks.py 
    ├── README.md
    └── setup.py

а затем вы сможете использовать его как:

from bagoftricks.bagoftricks import levenshtein, geofind

но после внесения изменений в структуру папок выполните: -

pip uninstall <your package name mostly mentioned in setup.py>

и переустановите пакет

тем временем проверьте 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(),
)
У установки

могут быть и другие параметры. Надеюсь, это сработает для вас.

Ответ 3

с обновленной структурой, которую вы опубликовали

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

в другую программу, вы можете выполнить следующее:

from bagoftricks import geofind
import bagoftricks; bagoftricks.geofind(); bagoftricks.bagoftriks.geofind()

Заметьте, что вы можете импортировать также wild card

from bagoftricks import *