首页 > 解决方案 > 难以理解数据是如何传递的

问题描述

所以我试图对我正在构建的游戏产生类似频闪的效果,而我目前拥有它的方式正在破坏我的帧速率,因为睡眠功能也适用于绘图功能。有人可以解释为什么会这样吗?还有我无法理解的逻辑。为什么我不能每 0.5 秒返回一次而不影响我在色调功能中的 0.1 睡眠?

这是代码类型的粗略演示。

from random import randint
import time
def rand_intr():
    r = randint(1,256)
    time.sleep(.5)
    return r

def rand_intg():
    g = randint(1,256)
    time.sleep(.5)
    return g

def rand_intb():
    b = randint(1,256)
    time.sleep(.5)
    return b

def hue():
    r = rand_intr()
    g = rand_intg()
    b = rand_intb()
    print(r, g, b)
    print('test')
    time.sleep(.01)

while True:
    hue()

标签: python

解决方案


sleep函数阻塞主线程。这意味着在从睡眠中“醒来”rand_intg之前不会运行。rand_intr同样,rand_intb必须等待rand_intg,并且hue必须等待前面的所有 3 个函数。这意味着在它可以完成任何工作之前必须等待的总时间hue至少是完成rand_intrrand_intg和所需的时间rand_intb

如果我们稍微修改您的示例并查看输出,我们可以理解发生了什么。

from random import randint
import time

def log_entry_exit(f):
    def wrapped():
        print("Entered {}".format(f.__name__))
        result = f()
        print("Leaving {}".format(f.__name__))
        return result
    return wrapped

@log_entry_exit
def rand_intr():
    r = randint(1,256)
    time.sleep(.5)
    return r

@log_entry_exit
def rand_intg():
    g = randint(1,256)
    time.sleep(.5)
    return g

@log_entry_exit
def rand_intb():
    b = randint(1,256)
    time.sleep(.5)
    return b

def hue():
    r = rand_intr()
    g = rand_intg()
    b = rand_intb()
    print(r, g, b)
    print('test')
    time.sleep(.01)

while True:
    hue()

在这里,我只是修改了您的函数,以便在我们进入和退出每个函数时打印一条消息。

输出是

Entered rand_intr
Leaving rand_intr
Entered rand_intg
Leaving rand_intg
Entered rand_intb
Leaving rand_intb
172 206 115
test
Entered rand_intr
Leaving rand_intr
Entered rand_intg
Leaving rand_intg
Entered rand_intb
Leaving rand_intb
240 33 135
test
...

在这里,可以清楚地看到每个sleep上的效果。hue在之前的功能完成之前,您无法打印 rgb 值或“测试”。

您可以做的是hue使用计时器回调定期调用您的函数,然后根据某种模式修改 rgb 值。有关如何使用基本的基于时间的机制定期执行函数的示例,请参阅关于执行周期性操作的这个 stackoverflow 问题 。

编辑

根据您对@jasonharper 的评论

如果您hue每 60 秒调用一次,那么您对生成随机 rgb 值的函数的调用以更快的速度发生是没有意义的,因为在hue.

您可以做的是hue每 60 秒调用一次,然后生成您的 rgb 值以在其中包含任何模式。

在我上面链接的帖子中通过@kev修改答案,

import time, threading
def update():
    # Do whatever you want here. 
    # This function will be called again in 60 seconds.
    # ...

    hue()

    # Whatever other things you want to do
    # ...

    threading.Timer(60.0, update).start()

def hue():
    r = rand_intr()
    g = rand_intg()
    b = rand_intb()
    print(r, g, b)
    # Don't call sleep.

if __name__ == "__main__":
    update()

现在您应该只调用update 一次,可能在代码的某些启动部分中,并删除sleep函数中的所有调用。


推荐阅读