[英]How to subclass Clock in Pyglet?
我想对pyglet.clock模块的Clock类进行子类化,但是当我使用schedule_interval时遇到一些麻烦:
以下代码不输出任何内容,并且如果根本不打勾,则对象c看起来像:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pyglet
class Clock(pyglet.clock.Clock):
def __init__(self):
super(Clock, self).__init__()
class Test(object):
def update(self, dt):
print dt
w = pyglet.window.Window()
@w.event
def on_draw():
w.clear()
t = Test()
c = pyglet.clock.Clock()
c.schedule_interval(t.update, 1/60.0)
pyglet.app.run()
但是下一个工作正常。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pyglet
class Clock(pyglet.clock.Clock):
def __init__(self):
super(Clock, self).__init__()
pyglet.clock.set_default(self)
class Test(object):
def update(self, dt):
print dt
w = pyglet.window.Window()
@w.event
def on_draw():
w.clear()
t = Test()
c = Clock()
c.schedule_interval(t.update, 1/60.0)
pyglet.app.run()
唯一的区别是Clock的构造方法中的pyglet.clock.set_default(self)句子。
我认为这还不清楚,或者至少不是将pyglet.clock.Clock子类化以拥有自己的派生Clock类的最佳方法。
问题:
有一些方法可以用Pyglet自动设置默认时钟吗?
有没有更优雅或Pythonic的解决方案?
可能没有pyglet.clock.set_default(self)行吗?
我还没有使用pyglet,但这是我的猜测:
你快到了。 您的第一个实现可能无法正常运行的原因是由于以下几行:
c = pyglet.clock.Clock()
c.schedule_interval(t.update, 1/60.0)
在这里,您正在创建一个新的Clock实例,并计划对其进行回调。 但是,实际上您实际上并没有将该时钟实例与pyglet相关联。 所以,当你跑步...
pyglet.app.run()
...您从未真正告诉pyglet新的时钟实例c
。 取而代之的是,pyglet将使用自己创建的实例。 从时钟模块中查看pyglet的源代码 ...:
# Default clock.
_default = Clock()
def set_default(default):
'''Set the default clock to use for all module-level functions.
By default an instance of `Clock` is used.
:Parameters:
`default` : `Clock`
The default clock to use.
'''
global _default
_default = default
def get_default():
'''Return the `Clock` instance that is used by all module-level
clock functions.
:rtype: `Clock`
:return: The default clock.
pyglet启动时,它将创建自己的时钟实例(称为_default
)。 如果要使用自己的,则需要使用set_default()
来替换它。 因此,要修复第一段代码,您可能需要执行以下操作之一:
c = pyglet.clock.get_default()
c.schedule_interval(t.update, 1/60.0)
...要么...
c = pyglet.clock.Clock()
pyglet.clock.set_default(c)
c.schedule_interval(t.update, 1/60.0)
上面的第二个例子毫无意义:pyglet已经为您提供了Clock的实例,因此您实际上只是在复制pyglet已经为您完成的工作。 无论哪种方式,您最终都会在pyglet使用的时钟上安排回调。
因此,现在应该说是的,您确实需要调用set_default()
。 这就是告诉pyglet使用对象而不是默认情况下创建的对象的方式。 现在,你可以想见,把这个set_default()
调用,你现在有它(在构造函数)。 但是,这样做可能更有意义...
class Clock(pyglet.clock.Clock):
def __init__(self):
super(Clock, self).__init__()
...
c = Clock()
pyglet.clock.set_default(c)
编辑 :
为了回答为什么要在构造函数之外执行此操作:
首先,作为一般经验法则,仅应使用构造函数来构造对象。 通过添加set_default,您不仅在构造对象,还在更改其他实体(pyglet.clock模块)的状态。 如下所述,这可能会引起混乱。 假设我写的代码看起来像这样...
c = MyClock()
c2 = UnpausedClock()
在此示例中,我以前实现了两种不同的时钟类型: NewClock
和UnpausedClock
。 UnpausedClock
仅在游戏未暂停时才考虑时间流逝。 如果我将set_default()
放在这两个新类的构造函数中,则UnpausedClock
将成为新的默认时钟(我不想要)。 通过不将set_default()
放在构造函数中,而是执行以下操作:
c = MyClock()
c2 = UnpausedClock()
pyglet.clock.set_default(c)
我的代码更加明确,也减少了混乱。
当然,代码将以任何一种方式工作,但我认为拥有set_default OUTSIDE构造函数可为您提供更大的灵活性,以便以后使用该类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.