Python functools аргументы частичного обратного вызова против свойств класса в методах обратного вызова - PullRequest
0 голосов
/ 04 октября 2019

Это может быть простой вопрос обратного вызова Python, но я работаю с потоками и сторонней библиотекой, поэтому извините (и уточнить), если я смешиваю разные проблемы.

Я смотрю на пример pika реализации поточно-безопасных ответов, которые используют обратный вызов и functools частичное в качестве способа передачи дополнительных аргументов в функцию обратного вызова.

def connect(self):
    connection = pika.BlockingConnection(
        pika.connection.URLParameters(params)
    )
    channel = connection.channel()
    cb = partial(self._on_message, connection=connection) 
    channel.basic_consume(queue=queue, on_message_callback=cb)


def _on_message(self, channel, method, properties, body, connection):
    print(connection)

Если я использую классы, могу ли япросто установить дополнительные аргументы (в данном случае соединение) как свойства класса, если свойство задано только один раз? Это эквивалентно тому же самому?

class MyClass:

    def connect(self):
        self.connection = pika.BlockingConnection(
            pika.connection.URLParameters(params)
        )
        channel = self.connection.channel()
        channel.basic_consume(queue=queue, on_message_callback=self._on_message)


    def _on_message(self, channel, method, properties, body):
        print(self.connection)

Я думаю, что это правильно, учитывая, что документы указывают на необходимость обратного вызова

The function to call when consuming with the signature on_message_callback(channel, method, properties, body)

Основываясь на этом, могу ли япреобразовать basic_ack в соответствии с примером

def example():
    cb = functools.partial(ack_message, channel, delivery_tag)
    connection.add_callback_threadsafe(cb)

def ack_message(channel, delivery_tag):
    if channel.is_open:
        channel.basic_ack(delivery_tag)

, чтобы получить следующее?

class MyClass

    def example(self):
        self.channel = channel
        self.delivery_tag = delivery_tag
        connection.add_callback_threadsafe(self.ack_message)

    def ack_message(self):
        if self.channel.is_open:
            self.channel.basic_ack(self.delivery_tag)

Не похоже, что ack_message требуется особая сигнатура параметра для add_callback_threadsafe to work.

Будет ли моя реализация со свойствами и методами класса обеспечивать безопасность потока этой реализации?

...