[英]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.