有没有办法在类中的装饰器中引用实例?

时间:2016-05-30 22:28:40

标签: python python-3.x

我正在使用pyglet并且pyglet使用装饰器来处理事件。我在我自己的班级中继承了pyglet.window.Window

class YApp(YData, pyglet.window.Window):

    def __init__(self, screen_width=1024, screen_height=768, fullscreen=False, locked_mouse=False):
        YData.__init__(self, "config.yur")
        if not self.data:
            self.data = {
                    "SCREEN_WIDTH": screen_width,
                    "SCREEN_HEIGHT": screen_height,
                    "FULLSCREEN": fullscreen,
                    "LOCKED_MOUSE": locked_mouse}
        self.write(self.data_name)
        pyglet.window.Window.__init__(self, self.data["SCREEN_WIDTH"], self.data["SCREEN_HEIGHT"], fullscreen=self.data["FULLSCREEN"])
        if self.data["LOCKED_MOUSE"]:
            self.set_exclusive_mouse()

    def run(self):
        pyglet.app.run()

    @self.event # HERE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    def on_key_press(key, modifiers):
        if key == pyglet.window.key.UP or key == pyglet.window.key.W:
            pass
        elif key == pyglet.window.key.DOWN or key == pyglet.window.key.S:
            pass
        elif key == pyglet.window.key.LEFT or key == pyglet.window.key.A:
            pass
        elif key == pyglet.window.key.RIGHT or key == pyglet.window.key.D:
            pass

这个装饰器通常使用pyglet.window.Window(例如@app.event)的“外部”实例在某些函数中应用于类之外。但是,我怎么能在类中的decorator中引用实例而不会得到NameError?如果我运行上面的代码,我得到:

Traceback (most recent call last):
  File "core.py", line 188, in <module>
    class YApp(YData, pyglet.window.Window):
  File "core.py", line 206, in YApp
    @self.event
NameError: name 'self' is not defined
Press any key to continue . . .

1 个答案:

答案 0 :(得分:3)

遗憾的是,这是不可能的。装饰器在定义类时执行,但是在定义类之前你不能(通常)创建类的实例。

但你不必这样做。如pyglet documentation所示,您可以通过简单地将它们定义为方法来添加事件处理程序。不要忘记self参数!

示例:

class YApp(YData, pyglet.window.Window):
    # I omitted __init__() and run() from your example

    # no need for a decorator
    def on_key_press(self, key, modifiers):
        pass  # your event handler