2014-09-21 30 views
1

如何避免类/方法/等的多个位置。在一个python包的命名空间中?考虑一个包含以下目录结构和代码的包:禁止子模块出现在名称空间w/__init__.py

dummyproj/ 
├── __init__.py 
└── main.py 

# main.py 
# ======= 
def dummy_func(): 
    print "hello world" 

# __init__.py 
# =========== 
from main import * 

有了这种结构,函数dummy_func可在包中找到。但是,它也可以从名为main的子模块中获得。例如:

>>> import dummyproj 
>>> dir(dummyproj) 
['__builtins__', 
'__doc__', 
'__file__', 
'__name__', 
'__package__', 
'__path__', 
'dummy_func', 
'main'] 
>>> dummyproj.dummy_func() 
hello world 
>>> dummyproj.main.dummy_func() 
hello world 

我将如何防止main不再出现在dummy_proj命名空间呢?我的理解是,将dummy_func的代码包含在__init__.py中将是错误的形式。

+0

因此,尽管'dummy_func'出现在两个地方,那么这是一种可以接受的做法吗? – 2014-09-21 22:04:16

+0

感谢您的帮助,卢卡斯。我对'requests'模块有点熟悉,所以这是一个有效的例子。你介意提交一些这样的答案作为答案,这样我可以将其标记为接受? – 2014-09-21 22:18:34

回答

1

你不能(在清洁和普遍接受的方式)。

但问题是,你为什么要?理想情况下,您的图书馆的用户将使用您的文档来了解您的图书馆的API,并且不必诉诸于使用dir()

如果我正在调试你的库,如果使用dir(),我可能会这样做,我不想让库的结构混淆。

所以刚才构建你的包是完全可以接受的,大多数图书馆都建立这样,你在你的例子做的方式:

  • 使用子模块/包,可能是几个人的水平,构建一个代码明智的方式
  • 然后,在顶层用于包装经常使用的功能/类提供方便的进口/等

一个非常好的考试PLE是requests模块:

import requests 
requests.get(url) 

get()功能被提供为convenience import at the top-level package,并且还记载,方式(quickstart docs | API docs)。但get()函数实际上生活在requests.api.get


另一个很好的例子是SQLAlchemy,甚至使用便利进口的几个层次:

Column类生活在sqlalchemy.sql.schema.Column。但它提供的便利导入为sqlalchemy.schema.Column,甚至在顶部为。 (尽管sqlalchemy.schema命名空间只是出于兼容性的原因,据我所知)。

0

有没有简单的方法来做到这一点。 (至少我知道)

你可以使用del来清理它,或者你可以使用函数来为你生成模块。像这样:(在__init__.py)。

def __init__mod(): 
    from main import dummy_func 

    g = globals() 
    g['dummy_func'] = dummy_func 

__init__mod() 
0

只需把它删掉你__init__.py文件:

# __init__.py 
# =========== 
from main import * 
del main 
相关问题