2014-02-12 125 views
14

所以我試圖做一個函數,跟蹤一個方法被調用的次數。 例如:有沒有一種方法可以跟蹤函數被調用的次數?

a = [1,2,3,4] 
a.pop() 

我想知道有多少次a.pop()是到目前爲止在這個例子叫,我會得到1 有沒有辦法做到這一點?

+1

很容易用你自己的功能來完成,而不是那些內置的功能。 – roippi

+0

創建一個全局變量或通過引用 – wipindipy10

+0

在函數'pop'中傳遞,您可以定義一個名爲'counter'的變量,然後在該函數的第一行執行'counter + = 1'。或類似的東西 – enginefree

回答

0

一個簡單的方法是每次調用函數時增加一個全局變量。

counter = 0 

a = [1,2,3,4]  
a.pop() 
counter += 1 
+0

我相信OP想知道調用了多少次'a.pop()',那麼你就不會那麼做。你基本上是在計算你的代碼在一個時間間隔內運行的次數。 – enginefree

+0

是的,我基本上是自己創建課堂,我需要計算一次調用方法的次數,但現在我已經明白了。感謝大家的幫助。 – user3050527

16

這並不適用於內置函數的工作,但一個有趣的方法是:

def myfunction(): 
    myfunction.counter += 1 
myfunction.counter = 0 

你給的功能屬性,所以每次調用屬性被更新。沒有全局變量需要。

內置插件是隻讀的。他們不能被修改。

+0

謝謝。這節省了我的一天。 – lanenok

1
counter = 0 

def pop(): 
    counter += 1 
    print counter 
    #other function code 

a = [1,2,3,4] 
a.pop() 

這應該解決您的問題,你應該能夠看到什麼被計數。 + 每次調用函數時,計數器將隨着函數的每次傳遞而增加和打印。

IF其內置的:

counter = 0 
    def newfunction(): 
     a = [1,2,3,4] 
     a.pop() 
     counter += 1 
     print counter 

在這個邏輯是,它會調用你的新功能進入功能被預製然後走出的內置函數,然後去紀念計數器增加。輸出你的計數器。

+0

iirc你必須全局變量,然後才能在全局範圍內修改它的函數 – icedtrees

+0

謝謝,我忘了補充一點。 :p – castaway2000

16

您可以使用一個裝飾器來跟蹤該函數被調用的次數。由於list是內置的,因此您不能修飾或替換其pop方法,因此您必須使用自己的列表類。

def counted(f): 
    def wrapped(*args, **kwargs): 
     wrapped.calls += 1 
     return f(*args, **kwargs) 
    wrapped.calls = 0 
    return wrapped 

class MyList(list): 
    @counted 
    def pop(self, *args, **kwargs): 
     return list.pop(self, *args, **kwargs) 

x = MyList([1, 2, 3, 4, 5]) 
for i in range(3): 
    x.pop() 

print x.pop.calls # prints 3 
+0

這簡直是美麗的。謝謝! –

1

踢,我寫了使用裝飾的答案:

class counter: 
    #wraps a function, to keep a running count of how many 
    #times it's been called 
    def __init__(self, func): 
     self.func = func 
     self.count = count 

    def __call__(self, *args, **kwargs): 
     self.count += 1 
     return self.func(*args, **kwargs) 

要使用它,簡單的裝飾功能。然後您可以通過檢查「count」屬性來檢查該函數運行了多少次。這樣做很好,因爲:

1.)沒有全局變量。計數直接與函數關聯。

2)你可以很容易地包裹內置功能,通過直接調用類:

sum_wrapped = counter(sum) 
sum_wrapped([1, 2 ,3, 4]) 
#outputs 10 
print sum_wrapped.count 
#outputs 1 

當然,這可以通過使用Decorators模塊,以保持文檔字符串和其他好東西原封不動加以改進。此外,要了解裝修工的概況以及工作原理,請查看this stackoverflow answer

1

一種方法是創建要計數屬性訪問該實例的代理:

from collections import Counter 

class CountingProxy(): 
    def __init__(self, instance): 
     self._instance = instance 
     self.count = Counter() 

    def __getattr__(self, key): 
     if hasattr(self._instance, key): 
      self.count[key] += 1 
     return getattr(self._instance, key) 


>>> l = [1,2,3,4,5] 
>>> cl = CountingProxy(l) 
>>> cl.pop() 
5 
>>> cl.append(10) 
>>> cl.index(3) 
2 
>>> cl.reverse() 
>>> cl.reverse() 
>>> cl.count 
Counter({'reverse': 2, 'pop': 1, 'append': 1, 'index': 1}) 
+1

這個計數*訪問*而不一定*調用*,這在某些情況下可能是一個重要的區別。例如'f = cl.pop; F(); F(); F();' – FogleBird

10

我用下面的小動作跟蹤函數調用的次數

def myfun(s,i=[0]):  
    print(s)  
    i[0]+=1 # mutable variable get evaluated ONCE 
    return i[0] 

>>> myfun('aaa') 
aaa 
1 
>>> myfun('bbb') 
bbb 
2 
相關問題