| 知乎专栏 |
self.parser = argparse.ArgumentParser(description='自动切割学习数据')
self.parser.add_argument('--source', type=str, default=None, help='图片来源地址')
self.parser.add_argument('--target', default=None, type=str, help='图片目标地址')
self.parser.add_argument('--imgsz', type=int, default=640, help='长边尺寸',metavar=640)
self.parser.add_argument('--clean', action="store_true", default=False, help='清理之前的数据')
self.parser.add_argument('--md5sum', action="store_true", default=False, help='使用md5作为文件名')
self.parser.add_argument('--uuid', action="store_true", default=False, help='重命名图片为UUID')
self.args = self.parser.parse_args()
import argparse
parser = argparse.ArgumentParser(description='Simple example')
parser.add_argument('name', help='Who to greet', default='World')
# Create two argument groups
foo_group = parser.add_argument_group(title='Foo options')
bar_group = parser.add_argument_group(title='Bar options')
# Add arguments to those groups
foo_group.add_argument('--bar_this')
foo_group.add_argument('--bar_that')
bar_group.add_argument('--foo_this')
bar_group.add_argument('--foo_that')
args = parser.parse_args()
usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT]
[--foo_this FOO_THIS] [--foo_that FOO_THAT]
name
Simple example
positional arguments:
name Who to greet
optional arguments:
-h, --help show this help message and exit
Foo options:
--bar_this BAR_THIS
--bar_that BAR_THAT
Bar options:
--foo_this FOO_THIS
--foo_that FOO_THAT
from termcolor import colored
# then use Termcolor for all colored text output
print(colored('Hello, World!', 'green', 'on_red'))
import sys
from termcolor import colored, cprint
text = colored('Hello, World!', 'red', attrs=['reverse', 'blink'])
print(text)
cprint('Hello, World!', 'green', 'on_red')
print_red_on_cyan = lambda x: cprint(x, 'red', 'on_cyan')
print_red_on_cyan('Hello, World!')
print_red_on_cyan('Hello, Universe!')
for i in range(10):
cprint(i, 'magenta', end=' ')
cprint("Attention!", 'red', attrs=['bold'], file=sys.stderr)
https://pypi.org/project/colorama/
pip install colorama
init(autoreset = False),当 autoreset = True 时自动恢复到默认颜色
#!/usr/bin/env python
from colorama import init, Fore, Back, Style
if __name__ == "__main__":
init(autoreset=True) # 初始化,自动恢复到默认颜色
print(Fore.RED + 'some red text')
print(Back.GREEN + 'and with a green background')
print(Style.DIM + 'and in dim text')
CLI 和 TUI 开发中我们常常会用到进度条,用于展示下载或执行进度等等。
Bar |################################| 200/200 [2 / 0 / 0:00:00] (None) ChargingBar ████████████████████████████████ 200/200 [2 / 0 / 0:00:00] (None) FillingSquaresBar ▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣ 200/200 [2 / 0 / 0:00:00] (None) FillingCirclesBar ◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉ 200/200 [2 / 0 / 0:00:00] (None) IncrementalBar |████████████████████████████████| 100% [0:00:02 / 0 / 0:00:00] PixelBar |⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿| 100% [0:00:02 / 0 / 0:00:00] ShadyBar |████████████████████████████████| 100% [0:00:02 / 0 / 0:00:00] Corolored |████████████████████████████████| 200/200 Spinner %(index)d - PieSpinner %(index)d ◷ MoonSpinner %(index)d ◑ LineSpinner %(index)d ⎼ PixelSpinner %(index)d ⡿ Counter 100 Countdown 0 Stack █ Pie ● Random |██████████████████████████████▊ | 96
安装
pip install progress
演示
from progress.bar import Bar
bar = Bar('Processing', max=20)
for i in range(20):
# Do some work
bar.next()
bar.finish()
执行结果
neo@MacBook-Pro-Neo ~/workspace/python % python3.9 progress-demo.py Processing |################################| 20/20
from progress.bar import Bar
import time
import random
length = 100
bar = Bar('Processing', max=length)
for i in range(length):
# Do some work
time.sleep(random.randrange(1, 5)*0.05)
bar.next()
bar.finish()
运行结果
Processing |######### | 31/100
将 # 换成 @ 符号,并且进度改为百分比。
bar = Bar('Loading', fill='@', suffix='%(percent)d%%')
演示
Loading |@@@@@@@@@@@@@ | 42%
from progress.bar import ChargingBar
import time
import random
length = 100
with ChargingBar('Processing', max=length) as bar:
for i in range(length):
# Do some work
time.sleep(random.randrange(1, 5)*0.05)
bar.next()
运行结果
Processing ███████████████████████∙∙∙∙∙∙∙∙∙ 73%
from progress.bar import FillingSquaresBar
import time
import random
length = 100
bar = FillingSquaresBar('Processing', max=length)
for i in range(length):
# Do some work
time.sleep(random.randrange(1, 5)*0.05)
bar.next()
bar.finish()
运行结果
Processing ▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢ 47%
bar = FillingCirclesBar('Processing', max=length)
for i in range(length):
# Do some work
time.sleep(random.randrange(1, 5)*0.05)
bar.next()
bar.finish()
运行结果
Processing ◉◉◉◉◉◉◉◉◉◉◉◉◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯ 41%
from progress.bar import IncrementalBar
import subprocess
cmd = "/usr/bin/memory_pressure | tail -n 1 | cut -d ':' -f2"
usage = 0
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, bufsize=64)
usage = int(p.stdout.readline().decode().replace(' ', '').replace('%', '').replace('\n', ''))
p.stdout.close()
p.wait()
length = 100
bar = IncrementalBar('Memory', max=length, suffix='%(index)d%%')
bar.goto(usage)
bar.finish()
Memory |████████████████▋ | 52%
安装
neo@MacBook-Pro-Neo ~ % pip install tqdm
neo@MacBook-Pro-Neo ~ % tqdm -h
Usage:
tqdm [--help | options]
Options:
-h, --help Print this help and exit.
-v, --version Print version and exit.
--desc=<desc> : str, optional
Prefix for the progressbar.
--total=<total> : int or float, optional
The number of expected iterations. If unspecified,
len(iterable) is used if possible. If float("inf") or as a last
resort, only basic progress statistics are displayed
(no ETA, no progressbar).
If `gui` is True and this parameter needs subsequent updating,
specify an initial arbitrary large positive number,
e.g. 9e9.
--leave : bool, optional
If [default: True], keeps all traces of the progressbar
upon termination of iteration.
If `None`, will leave only if `position` is `0`.
--ncols=<ncols> : int, optional
The width of the entire output message. If specified,
dynamically resizes the progressbar to stay within this bound.
If unspecified, attempts to use environment width. The
fallback is a meter width of 10 and no limit for the counter and
statistics. If 0, will not print any meter (only stats).
--mininterval=<mininterval> : float, optional
Minimum progress display update interval [default: 0.1] seconds.
--maxinterval=<maxinterval> : float, optional
Maximum progress display update interval [default: 10] seconds.
Automatically adjusts `miniters` to correspond to `mininterval`
after long display update lag. Only works if `dynamic_miniters`
or monitor thread is enabled.
--miniters=<miniters> : int or float, optional
Minimum progress display update interval, in iterations.
If 0 and `dynamic_miniters`, will automatically adjust to equal
`mininterval` (more CPU efficient, good for tight loops).
If > 0, will skip display of specified number of iterations.
Tweak this and `mininterval` to get very efficient loops.
If your progress is erratic with both fast and slow iterations
(network, skipping items, etc) you should set miniters=1.
--ascii=<ascii> : bool or str, optional
If unspecified or False, use unicode (smooth blocks) to fill
the meter. The fallback is to use ASCII characters " 123456789#".
--disable : bool, optional
Whether to disable the entire progressbar wrapper
[default: False]. If set to None, disable on non-TTY.
--unit=<unit> : str, optional
String that will be used to define the unit of each iteration
[default: it].
--unit-scale=<unit_scale> : bool or int or float, optional
If 1 or True, the number of iterations will be reduced/scaled
automatically and a metric prefix following the
International System of Units standard will be added
(kilo, mega, etc.) [default: False]. If any other non-zero
number, will scale `total` and `n`.
--dynamic-ncols : bool, optional
If set, constantly alters `ncols` and `nrows` to the
environment (allowing for window resizes) [default: False].
--smoothing=<smoothing> : float, optional
Exponential moving average smoothing factor for speed estimates
(ignored in GUI mode). Ranges from 0 (average speed) to 1
(current/instantaneous speed) [default: 0.3].
--bar-format=<bar_format> : str, optional
Specify a custom bar string formatting. May impact performance.
[default: '{l_bar}{bar}{r_bar}'], where
l_bar='{desc}: {percentage:3.0f}%|' and
r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, '
'{rate_fmt}{postfix}]'
Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt,
percentage, elapsed, elapsed_s, ncols, nrows, desc, unit,
rate, rate_fmt, rate_noinv, rate_noinv_fmt,
rate_inv, rate_inv_fmt, postfix, unit_divisor,
remaining, remaining_s, eta.
Note that a trailing ": " is automatically removed after {desc}
if the latter is empty.
--initial=<initial> : int or float, optional
The initial counter value. Useful when restarting a progress
bar [default: 0]. If using float, consider specifying `{n:.3f}`
or similar in `bar_format`, or specifying `unit_scale`.
--position=<position> : int, optional
Specify the line offset to print this bar (starting from 0)
Automatic if unspecified.
Useful to manage multiple bars at once (eg, from threads).
--postfix=<postfix> : dict or *, optional
Specify additional stats to display at the end of the bar.
Calls `set_postfix(**postfix)` if possible (dict).
--unit-divisor=<unit_divisor> : float, optional
[default: 1000], ignored unless `unit_scale` is True.
--write-bytes : bool, optional
If (default: None) and `file` is unspecified,
bytes will be written in Python 2. If `True` will also write
bytes. In all other cases will default to unicode.
--lock-args=<lock_args> : tuple, optional
Passed to `refresh` for intermediate output
(initialisation, iterating, and updating).
--nrows=<nrows> : int, optional
The screen height. If specified, hides nested bars outside this
bound. If unspecified, attempts to use environment height.
The fallback is 20.
--colour=<colour> : str, optional
Bar colour (e.g. 'green', '#00ff00').
--delay=<delay> : float, optional
Don't display until [default: 0] seconds have elapsed.
--delim=<delim> : chr, optional
Delimiting character [default: '\n']. Use '\0' for null.
N.B.: on Windows systems, Python converts '\n' to '\r\n'.
--buf-size=<buf_size> : int, optional
String buffer size in bytes [default: 256]
used when `delim` is specified.
--bytes : bool, optional
If true, will count bytes, ignore `delim`, and default
`unit_scale` to True, `unit_divisor` to 1024, and `unit` to 'B'.
--tee : bool, optional
If true, passes `stdin` to both `stderr` and `stdout`.
--update : bool, optional
If true, will treat input as newly elapsed iterations,
i.e. numbers to pass to `update()`. Note that this is slow
(~2e5 it/s) since every input must be decoded as a number.
--update-to : bool, optional
If true, will treat input as total elapsed iterations,
i.e. numbers to assign to `self.n`. Note that this is slow
(~2e5 it/s) since every input must be decoded as a number.
--null : bool, optional
If true, will discard input (no stdout).
--manpath=<manpath> : str, optional
Directory in which to install tqdm man pages.
--comppath=<comppath> : str, optional
Directory in which to place tqdm completion.
--log=<log> : str, optional
CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET.
from tqdm import tqdm import time for i in tqdm(range(100)): time.sleep(0.1) pass
演示效果
neo@MacBook-Pro-Neo ~/workspace/python % python3.9 /Users/neo/workspace/python/terminal/tqdm/demo.py 31%|██████████████▉ | 31/100 [00:03<00:07, 9.66it/s]
from tqdm import tqdm,trange import time for i in trange(100): time.sleep(0.1) pass
from tqdm import tqdm
import time
length = 50
# total 参数设置进度条的总长度
with tqdm(total=length) as bar:
for i in range(length):
time.sleep(0.05)
# 每次更新进度条的长度
bar.update(1)
from tqdm import tqdm import time length = 50 #total参数设置进度条的总长度 bar = tqdm(total=length) for i in range(length): time.sleep(0.05) #每次更新进度条的长度 bar.update(1) #关闭进度条 bar.close()
from tqdm import tqdm
import time
bar = tqdm(["加载", "执行", "保存", "完成"])
for step in bar:
time.sleep(1)
bar.set_description("当前进度 %s" % step)
from tqdm import tqdm
import time
import random
with tqdm(total=100, ncols=100) as progress:
progress.set_description("%s" % "netkiller")
for n in range(100):
time.sleep(random.randrange(1, 5) * 0.05)
progress.update(1)
/Users/neo/PycharmProjects/netkiller/.venv/bin/python /Users/neo/PycharmProjects/netkiller/test/test.py netkiller: 100%|██████████████████████████████████████████████████| 100/100 [00:13<00:00, 7.60it/s]
from time import sleep
from tqdm import trange, tqdm
import multiprocessing
import random
threads = list(range(5))
total = 100
def run(n):
name = multiprocessing.current_process().name
description = "#{} - {}".format(n, name)
for i in trange(total, desc=description, position=n, ascii=True):
sleep(random.randrange(1, 9)*0.1)
if __name__ == '__main__':
pool = multiprocessing.Pool(len(threads))
pool.map(run, threads)
pool.close()
pool.join()
效果展示
#0 - SpawnPoolWorker-1: 9%|######### | 9/100 [00:04<00:45, 1.98it/s] #1 - SpawnPoolWorker-4: 10%|#########9 | 10/100 [00:04<00:44, 2.01it/s] #2 - SpawnPoolWorker-2: 13%|############8 | 13/100 [00:04<00:34, 2.54it/s] #3 - SpawnPoolWorker-3: 10%|#########9 | 10/100 [00:04<00:50, 1.78it/s] #4 - SpawnPoolWorker-5: 14%|#############8 | 14/100 [00:04<00:28, 2.99it/s]
pip install alive-progress
from alive_progress import alive_bar
import time
items = range(10) # retrieve your set of items
with alive_bar(len(items)) as bar: # declare your expected total
for item in items: # iterate as usual
# process each item
bar() # call after consuming one item
time.sleep(1)
效果展示
|████████████████ | ▇▅▃ 4/10 [40%] in 3s (1.2/s, eta: 4s)
import tempfile
import httpx
import rich.progress
with tempfile.NamedTemporaryFile() as download_file:
url = "https://speed.hetzner.de/100MB.bin"
with httpx.stream("GET", url) as response:
total = int(response.headers["Content-Length"])
with rich.progress.Progress(
"[progress.percentage]{task.percentage:>3.0f}%",
rich.progress.BarColumn(bar_width=None),
rich.progress.DownloadColumn(),
rich.progress.TransferSpeedColumn(),
) as progress:
download_task = progress.add_task("Download", total=total)
for chunk in response.iter_bytes():
download_file.write(chunk)
progress.update(download_task, completed=response.num_bytes_downloaded)
https://github.com/foutaise/texttable/
pip install texttable
程序演示
from texttable import Texttable
table = Texttable()
table.add_rows([["Name", "Age", "Nickname"],
["Neo", 35, "netkiller"],
["李磊", 23, "Lee"],
["韩美美", 28, "May"]])
print(table.draw())
+--------+-----+-----------+ | Name | Age | Nickname | +========+=====+===========+ | Neo | 35 | netkiller | +--------+-----+-----------+ | 李磊 | 23 | Lee | +--------+-----+-----------+ | 韩美美 | 28 | May | +--------+-----+-----------+
max_width 设置报格最大宽度
table = Texttable(max_width= 160)
table.add_rows(tables)
print(table.draw())
set_header_align(self, array) 设置水平对齐
set_cols_align(self, array) 设置水平对齐
set_cols_valign(self, array) 设置垂直对齐
from texttable import Texttable
table = Texttable()
table.set_cols_align(["l", "r", "c"])
table.set_cols_valign(["t", "m", "b"])
table.add_rows([["Name", "Age", "Nickname"],
["Mr\nXavier\nHuon", 32, "Xav'"],
["Mr\nBaptiste\nClement", 1, "Baby"],
["Mme\nLouise\nBourgeau", 28, "Lou\n\nLoue"]])
print(table.draw())
print()
输出结果
+----------+-----+----------+ | Name | Age | Nickname | +==========+=====+==========+ | Mr | | | | Xavier | 32 | | | Huon | | Xav' | +----------+-----+----------+ | Mr | | | | Baptiste | 1 | | | Clement | | Baby | +----------+-----+----------+ | Mme | | Lou | | Louise | 28 | | | Bourgeau | | Loue | +----------+-----+----------+
from texttable import Texttable
table = Texttable()
for header in (Texttable.BORDER, Texttable.HEADER, Texttable.HLINES, Texttable.VLINES):
table.set_deco(header)
table.set_cols_align(["l", "r", "c"])
table.set_cols_valign(["t", "m", "b"])
table.add_rows([["Name", "Age", "Nickname"],
["Neo", 35, "netkiller"],
["李磊", 23, "Lee"],
["韩美美", 28, "May"]])
print(table.draw())
print("\n\n")
输出结果
+--------------------------+ | Name Age Nickname | | Neo 35 netkiller | | 李磊 23 Lee | | 韩美美 28 May | +--------------------------+ Name Age Nickname ======================== Neo 35 netkiller 李磊 23 Lee 韩美美 28 May Neo 35 netkiller 李磊 23 Lee 韩美美 28 May Name Age Nickname Neo 35 netkiller +--------------------------+ 李磊 23 Lee +--------------------------+ 韩美美 28 May +--------------------------+ Neo 35 netkiller +--------------------------+ 李磊 23 Lee +--------------------------+ 韩美美 28 May +--------------------------+ Neo 35 netkiller +--------------------------+ 李磊 23 Lee +--------------------------+ 韩美美 28 May Name | Age | Nickname Neo | 35 | netkiller 李磊 | 23 | Lee 韩美美 | 28 | May Neo | 35 | netkiller 李磊 | 23 | Lee 韩美美 | 28 | May Neo | 35 | netkiller 李磊 | 23 | Lee 韩美美 | 28 | May Neo | 35 | netkiller 李磊 | 23 | Lee 韩美美 | 28 | May
自定义行列线条字符
set_chars(self, array)
| Set the characters used to draw lines between rows and columns
|
| - the array should contain 4 fields:
|
| [horizontal, vertical, corner, header]
|
| - default is set to:
|
| ['-', '|', '+', '=']
set_chars(self, array) 数字的四个参数分别是:
默认是 ['-', '|', '+', '=']
下面这段代码模仿 MySQL 终端输出样式
table = Texttable()
table.set_cols_align(["r", "l", "c", "l", "l"])
table.set_cols_valign(["m", "m", "m", "m", "m"])
table.set_chars(['-', '|', '+', '-'])
table.set_cols_dtype(['i', 't', 'i', 't', 'a'])
table.add_rows([["id", "name", "age", "nickname", "ctime"],
[1, "Neo", 35, "netkiller", "2021-05-16 10:14:00"],
[2, "Tom", 23, "Lee", "2021-05-16 10:14:00"],
[3, "Jerry", 28, "May", "2021-05-16 10:14:00"]])
print(table.draw())
print()
+----+-------+-----+-----------+---------------------+ | id | name | age | nickname | ctime | +----+-------+-----+-----------+---------------------+ | 1 | Neo | 35 | netkiller | 2021-05-16 10:14:00 | +----+-------+-----+-----------+---------------------+ | 2 | Tom | 23 | Lee | 2021-05-16 10:14:00 | +----+-------+-----+-----------+---------------------+ | 3 | Jerry | 28 | May | 2021-05-16 10:14:00 | +----+-------+-----+-----------+---------------------+
怎么样,似曾相识吧?跟 mysql 命令中输出结果一致。
# Set datatype texttable.set_cols_dtype(["t", "i", "f", "a"]) # texttable objects supports five types of data types: # "t" refers to text # "f" refers to decimal # "e" refers to exponent # "i" refers to integer # "a" refers to automatic
from texttable import Texttable
table = Texttable()
table.set_deco(Texttable.HEADER)
table.set_cols_dtype(['t', # text
'f', # float (decimal)
'e', # float (exponent)
'i', # integer
'a']) # automatic
table.set_cols_align(["l", "r", "r", "r", "l"])
table.add_rows([["text", "float", "exp", "int", "auto"],
["abcd", "67", 654, 89, 128.001],
["efghijk", 67.5434, .654, 89.6,
12800000000000000000000.00023],
["lmn", 5e-78, 5e-78, 89.4, .000000000000128],
["opqrstu", .023, 5e+78, 92., 12800000000000000000000]])
print(table.draw())
输出结果
text float exp int auto ============================================== abcd 67.000 6.540e+02 89 128.001 efghijk 67.543 6.540e-01 90 1.280e+22 lmn 0.000 5.000e-78 89 0.000 opqrstu 0.023 5.000e+78 92 1.280e+22
texttable 本身不支持 ANSI 彩色文本输出,我以修复了该 Bug,已经想修复代码pull request 给作者。
Pull Request: https://github.com/foutaise/texttable/pull/75
我的代码库地址: https://github.com/netkiller/texttable
from texttable import Texttable
from colorama import Fore, Back, Style, init
table = Texttable()
table.set_chars(['-', '|', '+', '-'])
# table.set_cols_width([8, 5, 19])
table.add_rows([["Name", "Age", "Nickname"],
["Neo", 35, Fore.RED+"netkiller"+Fore.RESET],
["李磊", 23, Fore.GREEN+"Lee"+Fore.RESET],
["韩美美", 28, Fore.BLUE+"May"+Fore.RESET]])
print(table.draw())