进度条
如果您正在执行可能需要一些时间的操作,您可以将其告知用户。🤓
进度条¶
您可以使用 Rich 的进度显示 来显示进度条,例如
import time
import typer
from rich.progress import track
def main():
total = 0
for value in track(range(100), description="Processing..."):
# Fake processing time
time.sleep(0.01)
total += 1
print(f"Processed {total} things.")
if __name__ == "__main__":
typer.run(main)
您将要迭代的内容放在 Rich 的 track()
中,然后迭代它。
检查它
$ python main.py
---> 100%
Processed 100 things.
...实际上,它看起来会漂亮很多。✨ 但我无法在文档中向您展示动画。😅
颜色和信息将类似于以下内容
$ python main.py
Processing... <font color="#F92672">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</font><font color="#3A3A3A">━━━━━━━━━━</font> <font color="#AE81FF"> 74%</font> <font color="#A1EFE4">0:00:01</font>
旋转器¶
当您不知道操作需要多长时间时,可以使用旋转器。
Rich 允许您以复杂和高级的方式显示许多内容。
例如,这将显示两个旋转器
import time
import typer
from rich.progress import Progress, SpinnerColumn, TextColumn
def main():
with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
transient=True,
) as progress:
progress.add_task(description="Processing...", total=None)
progress.add_task(description="Preparing...", total=None)
time.sleep(5)
print("Done!")
if __name__ == "__main__":
typer.run(main)
我无法在文档中向您展示美丽的动画。😅
但在某个时间点,它将看起来像这样(想象它正在旋转)。🤓
$ python main.py
<font color="#A6E22E">⠹</font> Processing...
<font color="#A6E22E">⠹</font> Preparing...
您可以在 Rich 文档的进度显示部分 中了解更多信息。
Typer progressbar
¶
如果可以,您应该使用如上所述的 **Rich**,它具有更多功能,更高级,并且可以更美观地显示信息。✨
提示
如果您可以使用 Rich,请使用上面的信息、Rich 文档,并跳过本页面的其余部分。😎
但是,如果您无法使用 Rich,Typer(实际上是 Click)提供了一个简单的实用程序来显示进度条。
信息
typer.progressbar()
直接来自 Click,您可以在 Click 的文档 中了解更多信息。
使用 typer.progressbar
¶
提示
请记住,使用 Rich 来完成此操作会更好。😎
您可以使用 with
语句使用 typer.progressbar()
,例如
with typer.progressbar(something) as progress:
pass
您将要迭代的内容作为函数参数传递给 typer.progressbar()
。
import time
import typer
def main():
total = 0
with typer.progressbar(range(100)) as progress:
for value in progress:
# Fake processing time
time.sleep(0.01)
total += 1
print(f"Processed {total} things.")
if __name__ == "__main__":
typer.run(main)
因此,如果您有一个用户列表,这可能是
users = ["Camila", "Rick", "Morty"]
with typer.progressbar(users) as progress:
pass
使用 typer.progressbar()
的 with
语句为您提供了一个可以迭代的对象,就像您通常迭代的内容一样。
但是通过迭代这个对象 **Typer**(实际上是 Click),Click 会知道更新进度条。
users = ["Camila", "Rick", "Morty"]
with typer.progressbar(users) as progress:
for user in progress:
typer.echo(user)
提示
注意,代码块有两层。一层是 `with` 语句,另一层是 `for` 语句。
信息
这对于需要花费一些时间的操作非常有用。
在上面的例子中,我们使用 `time.sleep()` 来模拟这种情况。
检查它
$ python main.py
---> 100%
Processed 100 things.
设置进度条 `length`¶
提示
请记住,使用 Rich 来完成此操作会更好。😎
进度条是从可迭代对象的长度生成的(例如,用户列表)。
但是,如果长度不可用(例如,对于每次从 Web API 获取新用户的操作),你可以将显式的 `length` 传递给 `typer.progressbar()`。
import time
import typer
def iterate_user_ids():
# Let's imagine this is a web API, not a range()
for i in range(100):
yield i
def main():
total = 0
with typer.progressbar(iterate_user_ids(), length=100) as progress:
for value in progress:
# Fake processing time
time.sleep(0.01)
total += 1
print(f"Processed {total} user IDs.")
if __name__ == "__main__":
typer.run(main)
检查它
$ python main.py
---> 100%
Processed 100 user IDs.
关于带有 `yield` 的函数¶
如果你以前没有见过类似 `yield` 的东西,那就是一个 "生成器"。
你可以使用 `for` 循环迭代这个函数,在每次迭代中,它会返回 `yield` 的值。
`yield` 就像一个 `return`,它可以多次返回值,并允许你在 `for` 循环中使用该函数。
例如
def iterate_user_ids():
# Let's imagine this is a web API, not a range()
for i in range(100):
yield i
for i in iterate_user_ids():
print(i)
将打印每个“用户 ID”(这里只是从 `0` 到 `99` 的数字)。
添加 `label`¶
提示
请记住,使用 Rich 来完成此操作会更好。😎
你也可以设置一个 `label`
import time
import typer
def main():
total = 0
with typer.progressbar(range(100), label="Processing") as progress:
for value in progress:
# Fake processing time
time.sleep(0.01)
total += 1
print(f"Processed {total} things.")
if __name__ == "__main__":
typer.run(main)
检查它
手动迭代¶
如果你需要手动迭代某些东西并以不规则的方式更新进度条,你可以不传递可迭代对象,而是只传递一个 `length` 给 `typer.progressbar()`。
然后调用 `with` 语句中对象的 `.update()` 方法
import time
import typer
def main():
total = 1000
with typer.progressbar(length=total) as progress:
for batch in range(4):
# Fake processing time
time.sleep(1)
progress.update(250)
print(f"Processed {total} things in batches.")
if __name__ == "__main__":
typer.run(main)
检查它