简体   繁体   English

如何构造python包而不重复导入的顶级名称

[英]How to structure python packages without repeating top level name for import

I'm brand new at python package management, and surely have done something wrong. 我是python包管理的新手,肯定做错了。 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() . bagoftricks.py包含两个函数, levenshtein()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 UPDATE

So, I followed Avichal Badaya's instructions below, and removed one level of nesting. 所以,我按照下面的Avichal Badaya的说明,删除了一级嵌套。 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. 第一级“bagoftricks”很好。 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. 在你有一个setup.py和其他文件告诉包装系统他们需要知道什么。

You can then have the code directly in this module, or in a src directory. 然后,您可以直接在此模块或src目录中获取代码。 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. 使用__init__.py包含要导入的函数。 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: 一旦__init__.py变得太大,你想把它分成几个模块,给你这样的东西:

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

Your __init__.py should then import the functions from the various modules: 然后,您的__init__.py应该从各个模块导入函数:

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 同时检查你的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 *

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM