python手写简易进度条

这篇博客介绍了如何创建一个名为prog_bar的简单进度条工具,该工具支持手写无__len__方法的generator,以及嵌套使用。它通过不换行并在一行中重写内容来显示进度,类似于tqdm。博客提供了代码示例,展示了prog_bar如何应用于range、list、tuple、numpy.ndarray等,并演示了如何在循环中使用它来跟踪进度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(2023.9.4)更新:

  • 计时、估计剩余时间(ETA,Expected Time of Arrival);
  • 支持手写的、无实现 __len__ 的 generator;
  • 支持嵌套使用。

代码见 iTomxy/ml-template/utils/misc.py/prog_bar。例程:

# import time
# from utils import prog_bar

# 训练数据
X = ([1, 2], [3, 4], [5, 6], [7, 8])

# 手写 generator,无 `__len__` 也能用
def _generator(_X):
    for _x in _X:
        yield _x

print("before prog_bar")
# 嵌套循环,嵌套用 prog_bar 只打印最内层的 progress bar
for epoch in prog_bar("abc", "Epoch"): # string
    print('Epoch:', epoch)

    for i in prog_bar(range(15, 7, -2), "range"): # range
        print("\trange:", i)
        time.sleep(0.5)

        for x in prog_bar(X, "X"): # 数据
            print("\t\tX:", x)
            time.sleep(0.2)

    for x in prog_bar(_generator(X), "iterator"): # generator
        print("\titerator:", x)
        time.sleep(1)

print("after prog_bar:")

类似 tqdm[1] 的东西,效果:

  • 打印 [ <NOW> / <TOTAL> ] 式简易进度条。支持自定义前缀信息,形如:<MESSAGE>: [ <NOW> / <TOTAL> ]
  • 用法类似 tqdm,可套在 range、list、tuple、numpy.ndarray 上面用 for 遍历。手写的 generator 会报错:TypeError: object of type 'generator' has no len()支持,但 tqdm 支持。

原理就是不换行、并用 \r 重写行。

Code & Example

import time
import numpy as np
from collections.abc import Iterable


def prog_bar(iter_obj, prefix=None):
    """simple progress bar (better NOT to use `print` inside)
    Input:
        - iter_obj: iter_obj: range, tuple, list, numpy.ndarray
        - prefix: str, some message to show
    Ref:
        - https://stackoverflow.com/questions/3002085/how-to-print-out-status-bar-and-percentage
    """
    if isinstance(iter_obj, range):
        _start, _stop, _step = iter_obj.start, iter_obj.stop, iter_obj.step
    elif isinstance(iter_obj, Iterable):
        _start, _stop, _step = 0, len(iter_obj), 1
    else:
        raise NotImplemented

    n_digit = len(str(_stop))
    if prefix != None:
        template = "\r{}: [ %*d / %*d ]".format(prefix)
    else:
        template = "\r[ %*d / %*d ]"

    print("", end="")
    print(template % (n_digit, _start, n_digit, _stop), end="")
    for i, x in enumerate(iter_obj):
        yield x
        print(template % (n_digit, _start + (i + 1) * _step, n_digit, _stop), end="")
    print(template % (n_digit, _stop, n_digit, _stop))#, end="")


print("abcd")
for i in prog_bar(range(12, 103, 10)):
    time.sleep(1)
print("efg")

print("hijk")
for x in prog_bar([1, 2, 3], "list"):
    time.sleep(1)
print("lmn")

print("opq")
for x in prog_bar((4, 5, 6), "tuple"):
    time.sleep(1)
print("rst")

print("uvw")
for x in prog_bar(np.array([[7, 8, 9], [10, 11, 12]]), "np.ndarray"):
    time.sleep(1)
print("xyz")

References

  1. tqdm/tqdm
  2. How to print out status bar and percentage?
  3. Python脚本报错:DeprecationWarning: Using or importing the ABCs from ‘collections’ instead of from ‘collections.abc’ is deprecated since Python 3.3,and in 3.9 it will stop working import pymssql
<think>好的,我现在要帮用户解答如何提升Python编程基础的问题。首先,用户已经掌握了一些Python基础知识,但想进一步提升。我需要先理解用户的需求,他们可能处于初级阶段,希望巩固基础并进阶。 用户可能的目标是什么?可能是找工作、做项目,或者纯粹兴趣。不同的目标会影响学习路径,但不管怎样,基础是关键。需要先确保他们对Python的基本语法、数据结构、函数、模块等有扎实的理解。 接下来,用户可能需要知道如何系统性地提升。我应该分步骤来建议,比如巩固基础、实践项目、学习进阶知识、参与社区、代码优化等。每个步骤都需要具体的例子和方法,让用户有明确的行动方向。 另外,用户可能遇到的问题是不知道如何练习,或者练习项目太简单或太难。需要推荐一些经典的项目,如小游戏、工具脚本,这些项目能覆盖多个知识点,同时保持趣味性。还要强调从简单到复杂,逐步提升。 然后,代码规范和设计模式可能也是用户需要了解的,特别是如果他们想写出更专业的代码。比如PEP8规范、面向对象编程,这些内容能帮助他们的代码更易读和维护。 算法和数据结构是编程的基础,用户可能需要加强这方面的能力。推荐LeetCode或牛客网这样的平台,但要注意从简单题开始,避免挫败感。同时,结合实际问题来应用算法,这样理解更深刻。 参与开源项目可能对用户来说有点遥远,但其实有很多适合新手的项目。可以建议他们从贡献文档或简单bug修复开始,逐步积累经验。这不仅能提升技术,还能学习协作和版本控制工具的使用。 持续学习方面,用户可能需要资源推荐,比如书籍、在线课程、博客等。要选择适合他们当前水平的资料,比如《流畅的Python》适合进阶,而《Python Cookbook》提供实用技巧。 在常见误区部分,用户可能只关注语法而忽视实践,或者过度依赖复制代码。需要提醒他们避免这些陷阱,注重理解和调试能力的培养。 最后,保持耐心和兴趣很重要,编程提升需要时间。鼓励用户定期总结,参与社区讨论,这样能持续进步。 总结下来,回答需要结构清晰,步骤明确,提供具体的方法和资源,同时考虑到用户可能遇到的困难和误区,给予相应的建议。这样用户才能系统地提升他们的Python编程基础,从理论到实践,逐步进阶。</think>提升编程基础需要系统性的练习和持续积累,尤其是从“会一些基础”到“写出高质量代码”的过程中,以下是一些具体且可操作的策略,结合Python的特点整理: --- ### **一、巩固基础:查漏补缺** 1. **明确知识框架** - 对照以下核心知识点自检掌握程度: ✅ 变量与数据类型(列表/字典/集合的底层原理) ✅ 控制流(循环优化技巧,如`enumerate`替代索引) ✅ 函数(参数传递机制、闭包、装饰器) ✅ 面向对象(继承与组合的区别、`__slots__`优化内存) ✅ 异常处理(自定义异常、上下文管理器`with`) ✅ 模块与包(`__init__.py`的作用、相对导入) ✅ 文件操作(上下文管理、`pickle`序列化) 2. **刻意练习薄弱点** - 例如,若对装饰器不熟悉,尝试实现以下功能: - 记录函数执行时间的装饰器 - 带参数的装饰器(如根据参数缓存结果) ```python def timer(func): def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) print(f"{func.__name__}执行耗时: {time.time() - start:.2f}s") return result return wrapper ``` --- ### **二、项目驱动:从“玩具代码”到实战** 1. **经典小项目分层训练** - **Level 1**(巩固语法): - 猜数字游戏、简易计算器、文件批量重命名工具 - **Level 2**(综合应用): - 爬虫:用`requests`+`BeautifulSoup`抓取豆瓣电影Top250数据 - 数据分析:用`pandas`分析CSV文件并生成可视化图表(Matplotlib/Seaborn) - 自动化:用`selenium`模拟浏览器操作(如自动填写表单) - **Level 3**(工程化思维): - 用Flask/Django搭建一个博客系统(含用户认证、数据库操作) - 开发命令行工具(如用`argparse`实现文件格式转换工具) 2. **模仿优秀代码** - 在GitHub上搜索“Python awesome projects”,研究代码结构(例如: - 学习`requests`库的API设计(简洁优雅的链式调用) - 分析`tqdm`进度条的实现(上下文管理+终端控制) --- ### **三、进阶能力:写出“Pythonic”代码** 1. **掌握Python特有语法糖** - 列表推导式 vs 生成器表达式 ```python # 低效写法 squares = [] for i in range(10): squares.append(i**2) # Pythonic写法 squares = [i**2 for i in range(10)] ``` - 使用`collections`模块(`defaultdict`处理缺失键、`Counter`统计频率) - 活用`itertools`(如`groupby`分组、`product`多重循环优化) 2. **代码优化技巧** - 避免全局变量(使用类或闭包封装状态) - 用`functools.lru_cache`缓存递归函数结果 - 利用`sys`模块分析内存占用(如`sys.getsizeof`) --- ### **四、算法与数据结构:提升内功** 1. **针对性训练** - **必刷题分类**: - 字符串处理(反转、子串查找、正则表达式) - 链表操作(反转、环检测) - 二叉树遍历(递归与非递归实现) - 排序算法(手写快排/归并排序,分析时间复杂度) - **Python实现技巧**: - 用`heapq`模块实现优先队列 - 用`bisect`模块替代手动二分查找 2. **刷题策略** - 第一遍:按类型专项突破(如一周专注动态规划) - 第二遍:随机题目训练(模拟面试场景) - 推荐平台:LeetCode(Python标签题)、Codewars(分等级挑战) --- ### **五、工程化思维:超越脚本小子** 1. **代码规范与工具链** - 强制使用PEP8规范(配置`flake8`或`black`自动格式化) - 编写单元测试(`pytest`框架,覆盖率≥80%) - 使用`logging`替代`print`调试 - 掌握Git基础操作(分支管理、冲突解决) 2. **设计模式实践** - 实现常见模式: - 单例模式(限制类实例化次数) - 观察者模式(实现事件驱动系统) - 工厂模式(动态创建对象) - 示例:用策略模式实现多种排序算法切换 ```python class SortStrategy: def sort(self, data): raise NotImplementedError class QuickSort(SortStrategy): def sort(self, data): # 实现快排逻辑 pass class Sorter: def __init__(self, strategy): self.strategy = strategy def execute_sort(self, data): return self.strategy.sort(data) ``` --- ### **六、学习资源推荐** - **书籍**: - 《Effective Python》(90个改善Python编程的实用技巧) - 《Python Cookbook》(解决实际问题的代码片段) - **视频**: - Corey Schafer的Python教程(YouTube/B站) - 哈佛CS50 Python专题(edX) - **社区**: - Stack Overflow(提问时提供MCVE) - Real Python(深度技术文章) - Python官方邮件列表 --- ### **七、避免常见误区** 1. **不要“收藏即学会”**:每个教程至少敲一遍代码 2. **警惕复制粘贴**:理解每行代码的作用,尝试改写 3. **拒绝完美主义**:先写出能运行的代码,再逐步优化 4. **注重调试能力**:熟练使用`pdb`或PyCharm调试器 --- ### **附:30天提升计划示例** | 周次 | 重点 | 具体任务 | |------|-----------------------|----------------------------------------| | 1 | 基础强化 | 每天2小时重学一个核心知识点+配套练习 | | 2 | 小项目实战 | 完成爬虫+数据分析+自动化脚本各1个 | | 3 | 算法训练 | LeetCode每日2题(Easy/Medium) | | 4 | 工程化实践 | 为已有项目添加单元测试+文档+日志系统 | --- 编程能力的提升如同肌肉训练,需要持续的高质量输入(学习)和输出(编码)。建议每天保持至少1小时的高效编程时间,坚持3个月后会明显感受到质变。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值