Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python decorator可以正确地为递归函数计时_Python_Function_Recursion_Time_Decorator - Fatal编程技术网

Python decorator可以正确地为递归函数计时

Python decorator可以正确地为递归函数计时,python,function,recursion,time,decorator,Python,Function,Recursion,Time,Decorator,我正在研究一段代码,我想比较使用不同算法对列表排序所需的时间。我尝试使用decorator,但由于mergeSort函数是递归的,因此它为每个递归提供了结果。如果可能的话,我想找到一种方法来总结结果。因为我对装饰师很陌生,所以我不确定在这种情况下能做些什么。有没有一种方法可以通过装饰来达到这个目标 import random import functools import time def timeIt(func): @functools.wraps(func) def ne

我正在研究一段代码,我想比较使用不同算法对列表排序所需的时间。我尝试使用decorator,但由于mergeSort函数是递归的,因此它为每个递归提供了结果。如果可能的话,我想找到一种方法来总结结果。因为我对装饰师很陌生,所以我不确定在这种情况下能做些什么。有没有一种方法可以通过装饰来达到这个目标

import random
import functools
import time


def timeIt(func):
    @functools.wraps(func)
    def newfunc(*args, **kwargs):
        startTime = time.time()
        func(*args, **kwargs)
        elapsedTime = time.time() - startTime
        print('function [{}] finished in {} ms'.format(
            func.__name__, int(elapsedTime * 1000)))
    return newfunc


@timeIt
def mergeSort(L):
    if len(L) > 1:
        mid = len(L) // 2
        left = L[:mid] 
        right = L[mid:]
        mergeSort(left)
        mergeSort(right)
        i = j = k = 0
        while i < len(left) and j < len(right):
            if left[i] < right[j]:
                L[k] = left[i]
                i += 1
            else:
                L[k] = right[j]
                j += 1
            k += 1
        while i < len(left):
            L[k] = left[i]
            i += 1
            k += 1
        while j < len(right):
            L[k] = right[j]
            j += 1
            k += 1


@timeIt
def selectionSort(L):
    for fillslot in range(len(L) - 1, 0, -1):
        maxpos = 0
        for location in range(1, fillslot + 1):
            if L[location] > L[maxpos]:
                maxpos = location
        temp = L[fillslot]
        L[fillslot] = L[maxpos]
        L[maxpos] = temp


randomList = random.sample(range(10000), 10000)
mergeSort(randomList.copy())
selectionSort(randomList.copy())

你可以用另一个函数来包装它

import random
import functools
import time


def timeIt(func):
    @functools.wraps(func)
    def newfunc(*args, **kwargs):
        startTime = time.time()
        func(*args, **kwargs)
        elapsedTime = time.time() - startTime
        print('function [{}] finished in {} ms'.format(
            func.__name__, int(elapsedTime * 1000)))
    return newfunc



def mergeSort(L):
    if len(L) > 1:
        mid = len(L) // 2
        left = L[:mid]
        right = L[mid:]
        mergeSort(left)
        mergeSort(right)
        i = j = k = 0
        while i < len(left) and j < len(right):
            if left[i] < right[j]:
                L[k] = left[i]
                i += 1
            else:
                L[k] = right[j]
                j += 1
            k += 1
        while i < len(left):
            L[k] = left[i]
            i += 1
            k += 1
        while j < len(right):
            L[k] = right[j]
            j += 1
            k += 1



def selectionSort(L):
    for fillslot in range(len(L) - 1, 0, -1):
        maxpos = 0
        for location in range(1, fillslot + 1):
            if L[location] > L[maxpos]:
                maxpos = location
        temp = L[fillslot]
        L[fillslot] = L[maxpos]
        L[maxpos] = temp


@timeIt
def timedSelectionSort(L):
    selectionSort(L)

@timeIt
def timedMergeSort(L):
    mergeSort(L)


randomList = random.sample(range(10000), 10000)
timedSelectionSort(randomList.copy())
timedMergeSort(randomList.copy())
随机导入
导入功能工具
导入时间
def timeIt(功能):
@functools.wrapps(func)
def newfunc(*args,**kwargs):
startTime=time.time()
func(*args,**kwargs)
elapsedTime=time.time()-startTime
打印('function[{}]以{}ms'格式完成)(
函数名,int(elapsedTime*1000)))
返回newfunc
def合并排序(L):
如果len(L)>1:
mid=len(L)//2
左=左[:中]
右=L[中间:]
合并排序(左)
合并排序(右)
i=j=k=0
而iL[maxpos]:
maxpos=位置
温度=L[填充槽]
L[fillslot]=L[maxpos]
L[maxpos]=温度
@时间
def timedSelectionSort(L):
选择排序(L)
@时间
def timedMergeSort(L):
合并排序(L)
randomList=random.sample(范围(10000),10000)
timedSelectionSort(randomList.copy())
timedMergeSort(randomList.copy())
您可以在包装函数上设置一个属性(
\u在示例中输入的
)作为一个标志,这样,如果设置了该属性,它就可以知道它在递归调用中:

def timeIt(func):
    @functools.wraps(func)
    def newfunc(*args, **kwargs):
        if not hasattr(newfunc, '_entered'): # enter only if _entered is not set
            newfunc._entered = True # set _entered
            startTime = time.time()
            func(*args, **kwargs)
            elapsedTime = time.time() - startTime
            print('function [{}] finished in {} ms'.format(
                func.__name__, int(elapsedTime * 1000)))
            del newfunc._entered # remove _entered
    return newfunc

您可以编写一个专用于调用mergeSort的函数,如
mergeSortObserver
,并使用decorator对其进行修饰。由于这个特殊函数只被调用一次,因此您将获得所需的行为。
def timeIt(func):
    @functools.wraps(func)
    def newfunc(*args, **kwargs):
        if not hasattr(newfunc, '_entered'): # enter only if _entered is not set
            newfunc._entered = True # set _entered
            startTime = time.time()
            func(*args, **kwargs)
            elapsedTime = time.time() - startTime
            print('function [{}] finished in {} ms'.format(
                func.__name__, int(elapsedTime * 1000)))
            del newfunc._entered # remove _entered
    return newfunc