2013-07-03 33 views
14

我是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 

有什麼自然進口的祕密,如標準包使用,沒有多餘的頂級名稱進口?

回答

20

第一級 「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 

然後你仍然可以像以前那樣使用它們。

+0

謝謝,這是明確的和有益的,尤其是如何有效和正常生長它的尖端。這個問題當然是我的__init__.py語句。我不太明白它在層次結構中的位置,以及爲了縮短呼叫的位置。完美的作品。謝謝! – Mittenchops

1

關注以下結構:

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> 

並重新安裝包裝

同時檢查您的設置。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(), 
) 

安裝程序也可能有一些其他參數。我希望這個對你有用。

+0

是有沒有任何配置可以讓我用一個通話來完成?只是從bagoftricks導入levenshtein,geofind'而不是子模塊調用,'from bagoftricks.bagoftricks import levenshtein,geofind'? – Mittenchops

+0

@Mittenchops把'從'。 bagoftricks進口萊文斯坦,geofind'在'bagoftricks/__ __初始化。py' – amigcamel

1

與更新的結構,你貼

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 

到不同的程序,你可以做follwing

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

注意,你可以導入,以及外卡

from bagoftricks import * 
+0

雖然像'from module import *'這樣導入通配符被認爲是非常糟糕的做法,因爲它可能導致命名空間衝突。始終嘗試通過命名您導入的所有內容進行導入。 – kramer65

+0

是的 - 你是對的,但對於這個例子是好的 - 還要注意bagoftricks中的模塊被導入到命名空間bagoftricks中。 – silviud

+0

只是想知道;爲什麼這個例子很好?如果從bagoftricks中導入geofind,然後從其他模塊中導入一個也稱爲geofind的函數,則會發生衝突。我在這裏錯過了什麼?爲什麼這個例子與其他Python代碼不同?用通配符導入是一個不好的做法,一段時間。 – kramer65

相關問題