Python Executor - Übergabe der Funktion mit Argument als Argument

Aug 26 2020

Mein Ziel ist es, eine Funktion zu erstellen, mit der ich die Ausführung und den Ressourcenverbrauch einer anderen Funktion messen kann. Mit einem Tutorial habe ich Folgendes mit Pythons ThreadPoolExecutor erstellt:

from resource import *
from time import sleep
from concurrent.futures import ThreadPoolExecutor

class MemoryMonitor:
    def __init__(self):
        self.keep_measuring = True

    def measure_usage(self):
        max_usage = 0
        u_run_time = 0
        s_run_time = 0
        while self.keep_measuring:
            max_usage = max(max_usage, getrusage(RUSAGE_SELF).ru_maxrss)
            u_run_time = max(u_run_time, getrusage(RUSAGE_SELF).ru_utime) 
            s_run_time = max(s_run_time, getrusage(RUSAGE_SELF).ru_stime) 
        sleep(0.1) # run this loop every 0.1 seconds
        return [max_usage, u_run_time, s_run_time]

def execute(function):
    with ThreadPoolExecutor() as executor:
        monitor = MemoryMonitor()
        stats_thread = executor.submit(monitor.measure_usage)
        try:
            fn_thread = executor.submit(function)
            result = fn_thread.result()
            print("print result")
            print(result)
            print("print result type")
            print(type(result))
        finally:
            monitor.keep_measuring = False
            stats = stats_thread.result()
        print(stats)
        return result

def foo():
    i = 0
    while i < 3:
        print("foo")
        i+=1
    return 1

def bar(x):
    while x < 3:
        print("foobar")
        x+=1
    return 1

var = execute(foo)
print("Var = " + str(var))
var = execute(bar(0))
print("Var = " + str(var))

Wenn ich die Funktion foo als Argument an die ausgeführte Funktion übergebe , gibt sie die korrekten Ergebnisse aus und gibt den von foo zurückgegebenen Wert zurück.

Wenn ich die Funktion übergeben Bar in der gleichen Art und Weise, aber mit Bar selbst ein Argument erforderlich ist , die Funktion läuft (prints 3 mal) und dann die folgende Fehlermeldung erhalte ich:

result = self.fn(*self.args, **self.kwargs)
TypeError: 'int' object is not callable

Nach einigen Tests scheint der Teil, in dem ich feststecke, eine Funktion als Argument zu übergeben, wenn diese Funktion selbst ein Argument erfordert. Soweit ich den ThreadPoolExecutor verstehe, kapselt das Objekt fn_thread die Ausführung der übergebenen Funktion. Das Ergebnisobjekt sollte einfach das Ergebnis dieser Ausführung enthalten - was fehlt mir, dass dies nicht damit umgehen kann, dass eine Funktion mit einem Argument übergeben wird?

Antworten

3 AleksJ Aug 26 2020 at 15:08

Sie senden

bar(0) 

Anstatt von

bar, 0

Schauen Sie sich zur Verdeutlichung die Unterschrift des Submit an: submit (fn, * args, ** kwargs)

das Ergebnis von

bar(0)

ist eine Ganzzahl, und der Executor kann keine Ganzzahl aufrufen, da sie nicht "aufrufbar" ist, wie in der Fehlermeldung angegeben.