Dekorator wątków [Python]

Oct 27 2020

Próbuję stworzyć prosty program przy użyciu gniazda Python i biblioteki wątków. Chciałbym zautomatyzować następującą procedurę za pomocą dekoratora:

t = threading.Thread(target=function, args=(arg1, arg2))
t.start()

program jest zbudowany przy użyciu OOP, więc zdefiniowałem podklasę wewnątrz głównej, aby zawierała wszystkie dekoratory (przeczytałem o tej metodzie w tym artykule: https://medium.com/@vadimpushtaev/decorator-inside-python-class-1e74d23107f6). Dlatego mam taką sytuację:

class Server(object):

    class Decorators(object):

        @classmethod
        def threaded_decorator(cls, function):
            def inner_function():
                function_thread = threading.Thread(target=function)
                function_thread.start()
            return inner_function

    def __init__(self, other_arguments):
        # other code
        pass

    @Decorators.threaded_decorator
    def function_to_be_threaded(self):
        # other code
        pass

Ale gdy próbuję uruchomić, pojawia się następujący błąd: TypeError: function_to_be_threaded() missing one required argument: 'self'. Podejrzewam, że problem znajduje się w części, gdy wywołuję Threading.Thread (target = function), która w jakiś sposób nie przekazuje całej funkcji self.function_to_be_threaded. Dlatego jeśli wiesz, jak to naprawić, czy możesz mi powiedzieć? Czy możesz mi również powiedzieć, czy istnieje sposób na zaimplementowanie dekoratora, który akceptuje argument, który zostanie przekazany do klasy Thread jako args=(arguments_of_the_decorator)?

Bardzo dziękuję za poświęcony czas i przepraszam za mój angielski, nadal go ćwiczę

Odpowiedzi

1 napuzba Oct 27 2020 at 15:15

Użyj *argsskładni, aby przenieść argumenty, innymi słowy, użyj, *argsaby zebrać wszystkie argumenty pozycyjne jako krotkę i przenieść ją threading.Threadjako args.

import threading
import time
class Server(object):

    class Decorators(object):

        @classmethod
        def threaded_decorator(cls, function):
            def inner_function(*args):
                function_thread = threading.Thread(target=function,args=args)
                function_thread.start()
            return inner_function

    def __init__(self, count,sleep):
        self.count = count
        self.sleep = sleep

    @Decorators.threaded_decorator
    def function_to_be_threaded(self,id):
        for xx in range(self.count):
            time.sleep(self.sleep)
            print("{} ==> {}".format(id,xx))
           

>>> Server(6,1).function_to_be_threaded('a')
>>> Server(2,3).function_to_be_threaded('b')

a ==> 0
a ==> 1
a ==> 2
b ==> 0
a ==> 3
a ==> 4
a ==> 5
b ==> 1

zobacz także Jak mogę przekazywać argumenty z jednej funkcji do drugiej?