我希望函数成为我正在构建的类的一部分,但出现错误可能是装饰器函数将成为部门中的函数。有解决问题的办法吗?谢谢。
import engineio
class Websocket:
def __init__(self):
self.eio = engineio.Client()
self.eio.connect('http://localhost:5000')
self.eio.wait()
# get error in this function
@eio.on('connect')
def on_connect():
print('connection established')
答案 0 :(得分:3)
您不能在装饰器表达式引用实例属性的方法上使用装饰器。这是因为装饰器是在装饰函数创建时执行的。在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()
method接受处理程序作为第二个参数,但是您也可以使用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()
method会阻塞,直到连接结束才返回。通常,您不会将此类调用放在类的__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()