簡體   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