修改字符串模板以使用其他变量作为修饰符
Modifying a string template to use other variables as modifiers
我正在做一个助手 class 来简化基准测试循环,它包含 timing it's entire execution and each user defined amount of iterations
:
import time
class LoopTimer:
@staticmethod
def run(fn, start, end, step = 1, batch_size = 1, precision = 8,
template = 'iteration = {current_iteration} \t took {batch_elapsed_time:.8f}s \t total = {total_elapsed_time:.8f}s \t value = {value}'):
counter, counter_total = time.process_time(), time.process_time()
for i in range(start, end, step):
value = fn(i)
if i > 0 & i % batch_size == 0:
end = time.process_time()
print(template.format_map({
'current_iteration':i,
'batch_elapsed_time': end-counter,
'total_elapsed_time': end-counter_total,
'value': value,
'batch_start': counter,
'batch_end': end,
'loop_start': counter_total
}))
counter = time.process_time()
用户如何能够定义 LoopTimer.precision
以便无需创建新模板来限制当前的浮点精度 (8)?当然,可以通过像这样预格式化字符串来实现:
template = 'iteration = {current_iteration} \t took {batch_elapsed_time:.*precision1*f}s \t total = {total_elapsed_time:.*precision2*f}s \t value = '
print(template.replace('*precision1*', '1').replace('*precision2*', '9').format_map({
'current_iteration':i,
'batch_elapsed_time': end-counter,
'total_elapsed_time': end-counter_total,
'value': value,
'batch_start': counter,
'batch_end': end,
'loop_start': counter_total
}))
但在看到 str.format
功能后感觉有点脏。
编辑
格式化时也有一个奇怪的行为(使用上面定义的模板):
iteration = 97 took 0.00000000s total = 0.00000000s value = 158456325028528675187087900672
iteration = 98 took 0.00000000s total = 0.00000000s value = 316912650057057350374175801344
iteration = 99 took 0.00000000s total = 0.00000000s value = 633825300114114700748351602688
iteration = 100 took 0.00000000s total = 0.00000000s value = 1267650600228229401496703205376
iteration = 101 took 0.00000000s total = 0.00000000s value = 2535301200456458802993406410752
iteration = 102 took 0.00000000s total = 0.00000000s value = 5070602400912917605986812821504
如何解决这个问题?
允许一级嵌套格式,因此您可以将模板更改为:template = 'iteration = {current_iteration} took {batch_elapsed_time:.{precision}f}s total = {total_elapsed_time:.{precision}f}s value = {value}'
,然后在 format_map()
.
中添加 'precision': precision
\t
长度不固定,插入空格使当前子串8个字符宽,然后转到下一个子串。比如print("1\t23\t456\t7890")
的输出是
1 23 456 7890
、1
后接7个空格\t
、23
后接6个空格\t
、456
后接5个空格\t
,每个子串都是8个字符宽。因此,我在模板中使用固定的6个空格。
测试 运行 LoopTimer.run(lambda i: 2 ** i, 97, 103, precision = 4)
:
iteration = 97 took 0.0000s total = 0.0000s value = 158456325028528675187087900672
iteration = 98 took 0.0000s total = 0.0000s value = 316912650057057350374175801344
iteration = 99 took 0.0000s total = 0.0000s value = 633825300114114700748351602688
iteration = 100 took 0.0000s total = 0.0000s value = 1267650600228229401496703205376
iteration = 101 took 0.0000s total = 0.0000s value = 2535301200456458802993406410752
iteration = 102 took 0.0000s total = 0.0000s value = 5070602400912917605986812821504
我正在做一个助手 class 来简化基准测试循环,它包含 timing it's entire execution and each user defined amount of iterations
:
import time
class LoopTimer:
@staticmethod
def run(fn, start, end, step = 1, batch_size = 1, precision = 8,
template = 'iteration = {current_iteration} \t took {batch_elapsed_time:.8f}s \t total = {total_elapsed_time:.8f}s \t value = {value}'):
counter, counter_total = time.process_time(), time.process_time()
for i in range(start, end, step):
value = fn(i)
if i > 0 & i % batch_size == 0:
end = time.process_time()
print(template.format_map({
'current_iteration':i,
'batch_elapsed_time': end-counter,
'total_elapsed_time': end-counter_total,
'value': value,
'batch_start': counter,
'batch_end': end,
'loop_start': counter_total
}))
counter = time.process_time()
用户如何能够定义 LoopTimer.precision
以便无需创建新模板来限制当前的浮点精度 (8)?当然,可以通过像这样预格式化字符串来实现:
template = 'iteration = {current_iteration} \t took {batch_elapsed_time:.*precision1*f}s \t total = {total_elapsed_time:.*precision2*f}s \t value = '
print(template.replace('*precision1*', '1').replace('*precision2*', '9').format_map({
'current_iteration':i,
'batch_elapsed_time': end-counter,
'total_elapsed_time': end-counter_total,
'value': value,
'batch_start': counter,
'batch_end': end,
'loop_start': counter_total
}))
但在看到 str.format
功能后感觉有点脏。
编辑
格式化时也有一个奇怪的行为(使用上面定义的模板):
iteration = 97 took 0.00000000s total = 0.00000000s value = 158456325028528675187087900672
iteration = 98 took 0.00000000s total = 0.00000000s value = 316912650057057350374175801344
iteration = 99 took 0.00000000s total = 0.00000000s value = 633825300114114700748351602688
iteration = 100 took 0.00000000s total = 0.00000000s value = 1267650600228229401496703205376
iteration = 101 took 0.00000000s total = 0.00000000s value = 2535301200456458802993406410752
iteration = 102 took 0.00000000s total = 0.00000000s value = 5070602400912917605986812821504
如何解决这个问题?
允许一级嵌套格式,因此您可以将模板更改为:template = 'iteration = {current_iteration} took {batch_elapsed_time:.{precision}f}s total = {total_elapsed_time:.{precision}f}s value = {value}'
,然后在 format_map()
.
'precision': precision
\t
长度不固定,插入空格使当前子串8个字符宽,然后转到下一个子串。比如print("1\t23\t456\t7890")
的输出是
1 23 456 7890
、1
后接7个空格\t
、23
后接6个空格\t
、456
后接5个空格\t
,每个子串都是8个字符宽。因此,我在模板中使用固定的6个空格。
测试 运行 LoopTimer.run(lambda i: 2 ** i, 97, 103, precision = 4)
:
iteration = 97 took 0.0000s total = 0.0000s value = 158456325028528675187087900672
iteration = 98 took 0.0000s total = 0.0000s value = 316912650057057350374175801344
iteration = 99 took 0.0000s total = 0.0000s value = 633825300114114700748351602688
iteration = 100 took 0.0000s total = 0.0000s value = 1267650600228229401496703205376
iteration = 101 took 0.0000s total = 0.0000s value = 2535301200456458802993406410752
iteration = 102 took 0.0000s total = 0.0000s value = 5070602400912917605986812821504