2013-05-09 36 views
-2

我想用一個非常簡單的python代碼使用exec並列出調用函數而不是調用它們。如何在python中使用exec來列出函數調用?

如果我知道哪些函數會被調用,我可以創建一個字典,將名稱函數定義爲print,並將其用作exec的第二個參數。

我試圖使用由overwritting 的GetItem打印調用的函數的自定義詞典類,但exec是沒有幫助的發行:

TypeError: exec: arg 2 must be a dictionary or None 

有沒有一種方法可以自定義函數調用中通用的方式?

編輯

舉例來說,假設我有以下的配置文件,用Python編寫的:

user('foo') 
password('foo123') 
home('/home/foo') 

user('bar') 
password('bar123') 
home('/home/foo') 

我需要運行這個文件,並打印其中包含的信息。我可以做到這一點下面的Python程序:

d = { 'user': print, 'password': print, 'home: 'print } 
execfile(filename, d, {}) 

這種方法的問題是,我有所有存在於文件中的函數初始化d。我試圖使用自定義詞典,它在getitem上做了一些不同的操作,並獲得了上面的TypeError

+1

後一些代碼,請 – 2013-05-09 19:10:40

+4

我讀了3次,我仍然感到困惑。你想做什麼? – CppLearner 2013-05-09 19:10:50

+2

這是一個解決方案的實際問題是什麼? – 2013-05-09 19:12:55

回答

3

也許像下面這樣的東西?

class Printer(dict): 
    def __missing__(self, key): 
     def wrapped(*args, **kwargs): 
      print('{} called: args={}, kwargs={}'.format(key, args, kwargs)) 
     return wrapped 

code = ''' 
foo() 
bar(1, 2, baz=3) 
''' 

exec(code, Printer()) 

輸出:

foo called: args=(), kwargs={} 
bar called: args=(1, 2), kwargs={'baz': 3} 
+2

這回答了OP的直接問題「是否有一種通用方法來定製函數調用?」很好。而且你甚至可以通過讓'Printer .__ init__'捕獲globals()'來擴展它,所以'__missing__'可以獲取並調用真實函數(如果它是可調用的)。它仍然會錯過稱爲函數的表達式,在'exec'塊中定義的新函數等,但至少它會捕獲間接調用的函數。 – abarnert 2013-05-09 20:53:49

+0

這正是我想要做的!謝謝! – Penz 2013-05-14 16:20:40

3

我可能是錯的,但似乎你想要的是:

>>> the_functions_called_in('foo(); bar() + 4; lol(hello())') 
['foo', 'bar', 'lol', 'hello'] 

在這種情況下,而不是exec你想the ast module

>>> m = ast.parse('foo(); bar() + 4; lol(hello())') 
>>> [x.func.id for x in ast.walk(m) if isinstance(x, ast.Call)] 
['foo', 'lol', 'bar', 'hello'] 

該函數的參數存儲在args,starargs,keywordskwargs對象的屬性。

如果您想實際運行代碼並跟蹤哪些函數被調用(以及運行它們),請嘗試profiling

+0

我需要參數... – Penz 2013-05-09 19:17:59

+0

@Penz這些存儲在'Call'對象的屬性中,正如我在編輯中提到的那樣。 – Dougal 2013-05-09 19:22:29

+1

當然,如果你用'baz = foo; baz()'它會告訴你'baz'被調用而不是'foo',並且如果你用eval(「foo()」)來試試''它不會知道'foo'被調用, 等等。如果這是你想要做的事情,那就不可能正確編寫。 Dougal的版本儘可能接近你可以獲得的版本,並且它對於一些簡單的探索性目的可能是有用的,但是嘗試構建更強健的東西是一個非常非常糟糕的主意。 – abarnert 2013-05-09 19:32:40