循环中如何在新数据就绪显示前清屏?yfinance股票行情器优化
解决方案
方案1:先收集所有数据再批量显示
核心思路是先获取完所有股票的新数据,再清除屏幕并一次性打印所有内容,避免打印过程中被清屏,同时确保新数据就绪后再更新显示。
修改后的代码:
import yfinance as yf import time import os stocks = ["SPY", "TMUS"] def get_stock_data(): stock_data = [] for stock in stocks: ticker = yf.Ticker(stock) try: bid = ticker.info["bid"] open_price = ticker.info["regularMarketOpen"] change = open_price - bid stock_data.append((ticker.info["symbol"], bid, change)) except KeyError: # 处理数据缺失的情况 stock_data.append((stock, "N/A", "N/A")) return stock_data def main(): while True: # 先获取所有新数据 new_data = get_stock_data() # 清屏(兼容Windows和Linux/macOS) os.system('clear' if os.name == 'posix' else 'cls') # 一次性打印所有数据 for symbol, bid, change in new_data: print(f"{symbol}: {bid} Change: {change:.6f}" if change != "N/A" else f"{symbol}: {bid} Change: {change}") time.sleep(1) if __name__ == '__main__': main()
说明:
- 将原
check函数改为get_stock_data,专门收集所有股票的有效数据,返回结构化列表 - 主循环中先拿到全部新数据,再清屏,最后一次性打印所有内容,彻底解决打印中途清屏的问题
- 增加
try-except捕获字段缺失异常,避免程序意外崩溃
方案2:用ANSI控制码覆盖原有内容(无闪烁更新)
如果不想完全清屏,可以用ANSI控制码将光标移到屏幕顶部,直接覆盖原有内容,视觉上更流畅:
import yfinance as yf import time import os stocks = ["SPY", "TMUS"] def print_stock_data(): # 光标移到屏幕左上角 print('\033[H', end='') for stock in stocks: ticker = yf.Ticker(stock) try: bid = ticker.info["bid"] open_price = ticker.info["regularMarketOpen"] change = open_price - bid # 打印内容并清除该行剩余旧内容 print(f"{stock}: {bid} Change: {change:.6f}\033[K") except KeyError: print(f"{stock}: N/A Change: N/A\033[K") def main(): # 初始化清屏 os.system('clear' if os.name == 'posix' else 'cls') while True: print_stock_data() time.sleep(1) if __name__ == '__main__': main()
说明:
\033[H:将光标直接移动到屏幕左上角(行1列1)\033[K:清除当前光标位置到行尾的所有内容,确保旧数据被完全覆盖- 无需每次全量清屏,直接覆盖原有内容,减少屏幕闪烁感
方案3:异步并行获取数据(提升数据获取速度)
如果股票数量较多,逐个请求yfinance会导致数据获取耗时较长,用异步并行请求可以大幅缩短等待时间,让更新更及时。首先安装依赖:pip install aiohttp
代码示例:
import asyncio import aiohttp import yfinance as yf import time import os stocks = ["SPY", "TMUS"] async def fetch_stock_data(session, stock): # 传递异步会话给yfinance,实现异步请求 ticker = yf.Ticker(stock, session=session) try: bid = ticker.info["bid"] open_price = ticker.info["regularMarketOpen"] change = open_price - bid return (stock, bid, change) except KeyError: return (stock, "N/A", "N/A") async def get_all_stock_data(): async with aiohttp.ClientSession() as session: tasks = [fetch_stock_data(session, stock) for stock in stocks] # 并行执行所有股票数据请求 return await asyncio.gather(*tasks) def main(): while True: # 运行异步任务获取全部数据 stock_data = asyncio.run(get_all_stock_data()) # 清屏后打印 os.system('clear' if os.name == 'posix' else 'cls') for symbol, bid, change in stock_data: print(f"{symbol}: {bid} Change: {change:.6f}" if change != "N/A" else f"{symbol}: {bid} Change: {change}") time.sleep(1) if __name__ == '__main__': main()
说明:
- 用
aiohttp创建异步会话,并行请求所有股票的数据,相比逐个请求速度提升明显 - 确保在最短时间内拿到所有新数据,然后立即更新显示,减少延迟感
内容的提问来源于stack exchange,提问作者Swordfish II
相关产品推荐
相关产品推荐

