Декоратор потоков [Python]

Oct 27 2020

Я пытаюсь создать простую программу, используя сокет Python и библиотеку потоков. Я хочу автоматизировать следующую процедуру с помощью декоратора:

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

программа структурирована с использованием ООП, поэтому я определил внутри основного подкласс, содержащий все декораторы (я читал об этом методе в этой статье: https://medium.com/@vadimpushtaev/decorator-inside-python-class-1e74d23107f6). Поэтому у меня такая ситуация:

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

Но когда я пытаюсь запустить, я получаю следующее сообщение об ошибке: TypeError: function_to_be_threaded() missing one required argument: 'self'. Я подозреваю, что проблема находится в той части, когда я вызываю threading.Thread (target = function), который каким-то образом не передает всю функцию self.function_to_be_threaded. Следовательно, если вы знаете, как это исправить, вы можете мне сказать? Кроме того, не могли бы вы сказать мне, есть ли способ реализовать декоратор, который принимает аргумент, который будет передаваться в класс Thread как args=(arguments_of_the_decorator)?

Большое спасибо за ваше время и извините за мой английский, я все еще практикую его

Ответы

1 napuzba Oct 27 2020 at 15:15

Используйте *argsсинтаксис для перемещения аргументов, другими словами, используйте, *argsчтобы собрать все позиционные аргументы в виде кортежа и переместить его threading.Threadкак 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

см. также Как передать аргументы от одной функции к другой?