(整活向)史上最复杂的Hello Python World!

查看 77|回复 6
作者:hrh123   
print("Hello, World!"),恐怕是每个人学Python的第一个程序,这几天心血来潮,看到Hello  World就让我想到我初学编程时的样貌,于是打算简单地给它"重构"下,先亮代码:
import re
import tkinter as tk
import asyncio
class HelloWorldGUI:
    def __init__(self, master):
        self.master = master
        self.label = tk.Label(self.master)
        self.label.pack()
        self.hello_world_generator = self.hello_world()
    def hello_world(self):
        while True:
            yield "Hello, World!"
    def update_label(self):
        try:
            message = next(self.hello_world_generator)
        except StopIteration:
            self.hello_world_generator = self.hello_world()
            message = next(self.hello_world_generator)
        self.label["text"] = message
    def start(self):
        self.master.after(0, self.update_label)
        self.master.mainloop()
def coroutine_decorator(func):
    def wrapper(*args, **kwargs):
        coro = func(*args, **kwargs)
        next(coro)
        return coro
    return wrapper
@coroutine_decorator
def regex_coroutine(regex, target):
    while True:
        text = yield
        matches = re.findall(regex, text)
        for match in matches:
            target.send(match)
def main():
    root = tk.Tk()
    gui = HelloWorldGUI(root)
    regex = r"lo"
    @coroutine_decorator
    def print_match():
        while True:
            match = yield
            print(f"Match found: '{match}'")
    regex_coro = regex_coroutine(regex, print_match())
    loop = asyncio.get_event_loop()
    def schedule_regex_coroutine():
        text = gui.label["text"]
        regex_coro.send(text)
        loop.call_later(1, schedule_regex_coroutine)
    loop.call_soon(schedule_regex_coroutine)
    gui.start()
if __name__ == "__main__":
    main()
现在来详细分析下具体原理(结合代码看效果更佳):
[ol]
  • 导入必要的库,不多说了
  • 定义一个HelloWorldGUI类,用来封装GUI
  • 在类的初始化方法中,创建一个master属性,用于存储tkinter的根窗口对象;创建一个label属性,用于存储tkinter的标签对象,并将其添加到master中;创建一个hello_world_generator属性,用于存储一个生成器对象,该生成器可以不断产生“Hello,World!”字符串
  • 定义一个hello_world方法,该方法使用一个while循环.不断地yield“Hello,World!”字符串,用于创建上述生成器对象
  • 定义一个update_label方法,用于更新label的文本内容.该方法使用try-except语句,尝试从hello_world_generator中获取下一个字符串,并赋值给message变量.如果遇到StopIteration异常.说明生成器已经耗尽,那么重新创建一个新的生成器对象.并从中获取下一个字符串.然后将message变量赋值给label的text属性
  • 定义一个start方法,用于启动GUI的主循环.该方法使用master的after方法,在0毫秒后调用update_label方法;然后使用master的mainloop方法,进入GUI的事件循环
  • 定义一个coroutine_decorator函数,用于装饰协程函数.该函数接受一个函数作为参数,并返回一个包装函数.包装函数会调用原函数,并获取返回的协程对象.然后使用next函数预激活协程对象,并返回它
  • 使用coroutine_decorator装饰一个regex_coroutine函数,用于创建一个协程对象,该协程可以接收文本,并使用正则表达式查找匹配结果,并将其发送给另一个目标协程。该函数接受两个参数:regex和target.regex是一个正则表达式字符串,target是另一个协程对象.该函数使用一个while循环,不断地yield等待接收文本,并使用re模块的findall函数查找匹配结果.然后使用for循环遍历匹配结果,并将其发送给target协程
  • 定义一个main函数,用于执行主要逻辑
  • 在main函数中,创建一个tkinter的根窗口对象,并赋值给root变量;创建一个HelloWorldGUI对象,并传入root作为参数,并赋值给gui变量
  • 定义一个regex变量,赋值为r"lo",表示要查找的正则表达式
  • 使用coroutine_decorator装饰一个print_match函数,用于创建一个协程对象,该协程可以接收匹配结果,并打印出来.该函数使用一个while循环,不断地yield等待接收匹配结果,并赋值给match变量.然后使用print函数打印出匹配结果
  • 创建一个print_match协程对象,并赋值给print_match变量;创建一个regex_coroutine协程对象,并传入regex和print_match作为参数并赋值给regex_coro变量
  • 使用asyncio模块的get_event_loop函数获取当前事件循环对象,并赋值给loop变量
  • 定义一个schedule_regex_coroutine函数,用于定时调度regex_coro协程.该函数首先获取label的text属性,并赋值给text变量;然后使用regex_coro的send方法发送text给协程;最后使用loop的call_later方法,在1秒后再次调用schedule_regex_coroutine函数
  • 使用loop的call_soon方法,尽快调用schedule_regex_coroutine函数
  • 使用gui的start方法,启动GUI的主循环
  • 代码的最后,使用if语句判断是否为主模块,如果是,则调用main函数  
    [/ol]
    最终效果:生成一个GUI,中间有一个标签,显示Hello,World!的文本

    函数, 对象

  • px307   

    向大佬学习
    dazhaxie   

    狠人,事件循环用select或者epoll自己写一个
    py学徒   

    asyncio 是 Python 标准库中提供的一个异步编程框架。它允许您使用协程编写并发代码,通过多路复用 I/O 访问和运行网络客户端和服务器。
    通过使用 asyncio,您可以编写比传统同步编程更高效和可扩展的异步代码。它使用事件循环来管理多个任务的并发执行,使您能够异步执行 I/O 操作,而不会阻塞其他任务的执行。
    要使用 asyncio,通常需要使用 async 关键字将函数定义为协程,在其中等待异步操作。事件循环负责管理这些协程,安排它们的执行,并在它们等待 I/O 或其他非阻塞操作时进行切换。
    moruye   

    楼主真能整活,向楼主学习
    myconan   

    牛人教我学编程
    諦覠   

    第一次见到python版的复杂hello world
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部