2010-01-13 57 views
1

如何知道哪些成員模塊/軟件包定義?通過定義我的意思是:所有成員包/模塊定義?

somemodule.py

import os # <-- Not defined in this module 
from os.path import sep # <-- Not defined in this module 

I_AM_ATTRIBUTE = None # <-- Is defined in this module 

class SomeClass(object): # <-- Is defined also... 
    pass 

所以我需要某種形式的函數調用時會產生只有I_AM_ATTRIBUTESomeClass。我如何知道somemodule中定義了哪些?檢查__module__不起作用,因爲它沒有在模塊和屬性中定義(例如os包或sep屬性)。

顯然野生進口(from somemodule import *)也無法過濾這些,所以它甚至有可能嗎?

盡我所能得到的是:

import somemodule 

for name in dir(somemodule): 
    try: 
     value = getattr(somemodule, name) 
    except: 
     pass 
    else: 
     if hasattr(value, "__module__"): 
      if value.__module__ != somemodule.__name__: 
       continue 
     if hasattr(value, "__name__"): 
      if not value.__name__.startswith(__name__): 
       continue 
     print "somemodule defines:", name 

注意到os出來,但葉sep

+1

閱讀源代碼有什麼問題?你可以通過閱讀來細想這一點嗎?爲什麼不簡單閱讀? – 2010-01-13 11:07:30

回答

1

「define」是什麼意思?對我而言,定義爲意味着某些符號是模塊公共接口的一部分。這與您嘗試使用該術語的方式相似,包括在您的示例中,但如果您有某種目的與此定義不一致,則必須澄清關於您的真實性的問題試圖去做。這使得它文檔問題

所以你不知道模塊定義了什麼,有些導入的東西可能仍然是「在該模塊中定義的」或「定義爲該模塊的公共接口的一部分」。這通常在從私有模塊(包括C擴展模塊)導入時發生。

爲了你自己的模塊,使用__all__(能做到這一點easily)或非正式的下劃線前綴用於非公有制(例如_private_var = 42)。這兩個約定都被help()所識別,並且應該被其他文檔生成器使用。

+0

嘿,我敢打賭你讀了我以前的問題......因爲我試圖做文檔生成器(實際上是改進Sphinx)來執行自動包文檔,並且思考如果模塊沒有'__all__',我們應該記錄什麼東西?我可能會結束使用上面的代碼*如果*'__all__'沒有被定義......它至少會刪除「os」,並關閉這樣的導入。 – Ciantic 2010-01-13 13:04:49

+0

不,實際上我沒有讀過它,但是我刺殺了你真正想做的事情,而不是嘗試修復你嘗試的解決方案。 :) – 2010-01-13 13:09:03

+0

如果沒有\ _ \ _ all \ _ \ _,記錄所有不以下劃線開頭的文字,並要求作者添加\ _ \ _ all \ _ \ _,如果這不符合要求。如果你想添加諸如「(這可能是一個實現細節)」的通知,你可以檢測到的東西,比如導入的模塊,這也是合理的,但很難判斷它們是否是接口的一部分。 (例如,os.path是接口的一部分,但是是一個單獨的模塊。) – 2010-01-13 13:12:06

1

有沒有辦法做到這一點。這是因爲簡單的屬性(例如I_AM_ATTRIBUTE)就是存儲在模塊字典中的值。當它們被複制到另一個模塊時,它們也被放置在該模塊的字典中,並且無法分辨哪個是原始位置。您只能使用提供__module__屬性的對象(如類和函數)進行分析。

關於野生進口,在您的示例上運行from somemodule import *將導入所有屬性,包括ossep。如果一個軟件包提供了一個__all__變量,通配符將導入其中包含的名稱。否則,它將導入所有不以下劃線開頭的名稱,而不管它們最初來自哪個模塊。

+0

我編輯了這個問題,我還發現如果使用'__name__'進行檢查,「os」可以留下。 – Ciantic 2010-01-13 10:49:23