Вы не можете использовать декоратор в методе, где выражение декоратора ссылается на атрибут экземпляра.Это потому, что декораторы выполняются , когда создается функция, которую они декорируют .Внутри тела оператора class
это означает, что когда применяются декораторы, класс еще не существует, и без класса также не может быть никаких экземпляров.
У вас есть два варианта:
Просто вызовите self.eio.on('connect')
в __init__
вашего класса, передав связанный метод:
class Websocket:
def __init__(self):
self.eio = engineio.Client()
self.eio.connect('http://localhost:5000')
self.eio.on('connect', self.on_connect)
# don't call wait, see below
def on_connect(self):
print('connection established')
Это работает, потому что к тому времени __init__
вас называютиметь класс и экземпляр этого класса (на который ссылается self
), а self.on_connect
возвращает ссылку на связанный метод (при вызове ему будет передано self
).@....
синтаксис декоратора - это просто синтаксический сахар, у вас нет для его использования.engineio.Client.on()
метод принимает обработчик в качестве второго аргумента, но вы также можете использовать self.eio.on('connect')(self.on_connect)
, который является буквальным переводом того, что делает синтаксис декоратора.
Используйте вложенную функцию внутри __init__
и украсьте это:
class Websocket:
def __init__(self):
self.eio = engineio.Client()
self.eio.connect('http://localhost:5000')
@self.eio.on('connect')
def on_connect():
print('connection established')
# don't call wait, see below
but that makes it much harder to use that function directly from other code.
Обратите внимание, что engineio.Client.wait()
метод блокирует, он не возвращаетДо тех пор, пока соединение не закончилось.Обычно вы не помещаете такой вызов в метод __init__
класса!
Использование класса для обработки событий engineio
- это замечательно, но не запускайте клиентское соединение из класса.Я бы сделал это вместо:
class Websocket:
def __init__(self, socket_url):
self.eio = engineio.Client()
self.eio.connect(socket_url)
self.eio.on('connect', self.on_connect)
# other registrations
def on_connect(self):
# handle connection
# other handlers
def wait(self):
self.eio.wait()
websocket = Websocket('http://localhost:5000)
websocket.wait()