2014-03-06 71 views
0

我有一個python源文件,其中定義了一個類,並從另一個模塊中導入了一個類。從本質上講,這種結構:限制.py文件中的哪些類可以從其他地方導入

from parent import SuperClass 
from other import ClassA 

class ClassB(SuperClass): 
    def __init__(self): pass 

我想要做的就是看這個模塊中用於在那裏定義的所有類,只有找到ClassB的(和忽略ClassA的)。 ClassA和ClassB都擴展了SuperClass。

原因是我有一個在運行時加載的插件目錄,我通過在每個.py文件上進行自省並加載擴展超類的類來獲得插件類的完整列表。在這種特殊情況下,ClassB使用插件ClassA爲它做一些工作,所以依賴於它(ClassA同時不依賴於ClassB)。問題是,當我從目錄中加載插件時,我得到2個ClassA實例,因爲它從ClassA的文件中獲得一個,而從ClassB的文件中獲得一個。

對於包有辦法:

__all__ = ['module_a', 'module-b'] 

明確列出可以導入的模塊,但住在__init__.py文件,每個插件是一個.py文件不在目錄它自己的權利。

那麼問題是:我可以限制訪問.py文件中的類,還是必須使它們中的每一個都具有其自己的init文件的目錄?或者,還有其他一些聰明的方法可以區分這兩個類嗎?

回答

1

你的意思是「包裝有方法......」。實際上,這適用於每個模塊(__init__.py模塊,只是具有特殊的語義)。在插件模塊中使用__all__就是這樣。

但請記住:__all__只限制您使用from xxxx import *導入;您仍然可以訪問模塊的其餘部分,並且無法避免使用標準的Python導入機制。

如果您正在使用某種主動內省技術(例如,探索模塊中的名稱空間,然後從中導入類),則可以檢查該類是否來自與模塊本身相同的文件。

你也可以實現自己的進口機制(使用importlib,例如),但可能是矯枉過正...

編輯:對於「檢查類來自同一模塊」:

說,我有兩個模塊,mod1.py

class A(object): 
    pass 

mod2.py

from mod1 import A 

class B(object): 
    pass 
012現在

,如果我這樣做:

from mod2 import * 

我已經導入都AB。但...

>>> A 
<class 'mod1.A'> 
>>> B 
<class 'mod2.B'> 

如您所見,這些類攜帶有關它們起源的信息。實際上,您可以馬上查看:

>>> A.__module__ 
'mod1' 
>>> B.__module__ 
'mod2' 

使用該信息,您可以輕鬆區分它們。

+0

re:「for packages ...」,好點,我編輯了這個問題 –

+0

我沒有意識到你可以把'__all__'放在模塊中 - 有用的知道,謝謝。不幸的是,這並沒有抓住這個特殊的癢。但是,檢查課程來自模塊可能工作的相同文件 - 將不得不調查如何做到這一點! –

+0

太棒了!謝謝。 –

相關問題