簡體   English   中英

在包中隱藏模塊導入

[英]Hiding module imports in package

我有一個小包,其中包含一些依賴項,例如 pandas 和 gensim。 文件結構是這樣的

/package
    __init__.py
    agg_clean.py

__init__.py文件中,我import agg_clean以便我能夠以鏈接的方式訪問這些函數,例如:

import package as pkg
pkg.agg_clean.function()

但是,我在agg_clean.py有幾個導入語句(pandas、os 等)。 當我執行上述鏈接導入時,我還可以訪問agg_clean的導入,例如pkg.agg_clean.os.listdir()

如何在包導入中隱藏各種模塊的導入?

tl;dr你不能干凈利落。 或者更准確地說,你不應該擔心這樣的事情。

在這種情況下沒有namespace collisions ,因為 os 模塊是在pkg.agg_clean.os名稱下加載的。 如果用戶想使用您導入的 os 包,讓他們這樣做沒有壞處。 最重要的是,沒有什么方法可以阻止他們這樣做。

這里有一些有趣的事情要記住。 取以下可以被另一個python腳本導入的python模塊:

# module_im_importing.py
import os as _os

__all__ = ["echo"]

name_not_available = 'some_constant_string'

def echo(object):
    pass

如果您的用戶使用import module_im_importing裸模塊,則所有定義的變量都可以在名稱module_im_importing下用於其環境。

>>> import module_im_importing
>>> dir()  # Lookup local namespace
['__builtins__', '__doc__', '__name__', '__package__', 'module_im_importing']
>>> dir(module_im_importing)  # See defined items in your package.
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'echo', 'name_not_available', 'os']

如果他們改為from module_im_importing import * (不鼓勵這樣做),則行為略有不同:

>>> from module_im_importing import *
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'echo']

這會導致將文件module_im_importing.py定義的名稱導入到用戶的本地命名空間中。 因為我們在您的模塊中使用了__all__ ,所以只有__all__中定義的項目才會從您的模塊導入到用戶本地命名空間。 例如,如果您定義了一個像echo這樣的函數與他們可能正在使用的另一個包沖突,這可能會污染他們的命名空間。

這就是為什么在PEP8中顯然不贊成通配符導入的原因 從文件:

Wildcard imports (from <module> import *) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools.

無論如何,請不要為這樣的事情擔心。 如果您的模塊的用戶不遵循 PEP8,這只是一個問題,並且無論如何都應該向他們展示他們的方式的錯誤。 請記住,在 Python 中, We're all consenting adults here

這實際上只是 python 模塊工作方式的副作用。 您導入到模塊中的任何內容都可以作為該模塊中的頂級對象使用。 大多數人不擔心它,只是使用規范的導入路徑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM