2012-02-03 120 views
5
def c(): 
    def a(): 
     print dir() 

    def b(): 
     pass 

    a() 

c() 

可能是一個非常簡單的問題,但我似乎無法通過Google搜索找到答案。我有上面的代碼,我想要一個方法來打印包含方法a和b的命名空間,即我希望它打印它被調用的點形式的命名空間。這可能嗎?最好在Python 2.x的在Python中訪問父命名空間

+0

我會嘗試全局()在Python 3有另一種方式做到這一點,以及 – 2012-02-03 14:50:56

+1

你爲什麼要這麼做? – 2012-02-03 14:58:20

+0

我已經在兩個答案的評論中解釋過:基本上我正在爲我們的學生在我們的在線測試應用程序中尋找漏洞。看起來是正確的,我們需要阻止學生對測試代碼進行反向工程以找到解決方案。 (當然,任何聰明的學生也應該有足夠的技能來通過練習) – nvcleemp 2012-02-03 15:09:26

回答

5

您可以使用inspect模塊從標準Python庫:

import inspect 

def c(): 
    def a(): 
     frame = inspect.currentframe() 
     print frame.f_back.f_locals 

    def b(): 
     pass 

    a() 

c() 

frames使用後應刪除,見note


對評論的迴應。

可能的辦法限制檢查功能,對於學生:

import sys 
sys.modules['inspect'] = None 
sys._getframe = None 
+0

壞主意。這是昂貴的和骯髒的 – 2012-02-03 14:58:05

+0

其實,這正是我所害怕的可能性:學生可以使用檢查來打印我們用來測試他們的練習的功能的來源。謝謝。現在我有一個可能的攻擊,這是由我來找到一種方法來防止它 – nvcleemp 2012-02-03 15:04:15

+0

@ nvcleemp,我認爲可以限制'inspect'和'sys._getframe'的使用。 – reclosedev 2012-02-03 15:14:31

2

我會去與locals()這樣的:

def c(): 
    def a(locals_): 
     print locals_ 

    def b(): 
     pass 

    a(locals()) 

c() 
+0

是的,這是行得通的,但我不能改變函數的簽名a,我不能改變從哪個點它被稱爲。 (基本上,我試圖找到我的學生可以使用哪些攻擊來發現我們的在線測試應用程序中如何檢查解決方案) – nvcleemp 2012-02-03 14:57:01

+0

爲什麼您將學生代碼與一些代碼混合/插入?看起來很奇怪。爲什麼不能像模塊一樣導入並定期調用函數。或者eval,聽起來更簡單。或者,使用RestrictedPython來確保安全。 – Ski 2012-02-03 15:11:37

+0

我們使用現有的網站(spoj.pl),但已經撰寫了一些自定義評委來爲我們的學生提供更多反饋。其中一名評委拿着學生代碼,運行它,然後運行doctest,並給學生提供這個doctest的結果。看起來我有點過早了:我認爲他們可以使用inspect.getsource,但是由於被執行的代碼是生成的,因此似乎無法以這種方式獲得源代碼。 – nvcleemp 2012-02-03 15:19:10