繁体   English   中英

如何在Pyglet中子类化Clock?

[英]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()

在此示例中,我以前实现了两种不同的时钟类型: NewClockUnpausedClock 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM