在Pythonreadline、readlines、read等常用接口是什么
In Python What is the common interface of readline, readlines, read, etc
我正在尝试使用 function I came up with,这样我就可以添加一个进度条显示文件已读取的数量,但是当我这样做时:
file_path = 'file'
f = open(file_path, 'rb')
file_size = os.path.getsize(file_path)
def new_readline(self, size=-1):
print(self.tell(), '/', file_size)
f.read = hook(new_readline, f.read)
如果我尝试用 f.readlines()
读取文件的行,它不会显示任何内容,它只会在我使用 f.readline()
.
时显示输出
即使我挂了f.read
我还是一无所获
那么,我可以挂钩的所有数据读取方法调用的通用方法是什么(不一定是 readline 方法,只是它们都调用自己的东西)?
最后我不得不将钩子附加到 read()
方法,但它有效!
无论如何,这里有完整的代码供感兴趣的人使用:
from types import MethodType
import os
ESCAPE = {
'c': { # colours
'fg': { # foreground
'b': '30', # black
'r': '31', # red
'g': '32', # green
'y': '33', # yellow
'u': '34', # blue
'p': '35', # purple
'c': '36', # cyan
'w': '37', # white
},
'bg': { # background
'b': '40', # black
'r': '41', # red
'g': '42', # green
'y': '43', # yellow
'u': '44', # blue
'p': '45', # purple
'c': '46', # cyan
'w': '47', # white
}
},
's': { # style
'n': '0', # none
'b': '1', # bold
'u': '2', # underline
'n1': '3', # negative1
'n2': '5', # negative2
},
't': '3[{s};{fg};{bg}m', # template
'util': {
'hide': '3[?25l',
'show': '3[?25h',
'go_up': '3[{}A',
'go_down': '3[{}B',
'erase_line': '3[K',
}
}
# Open a file but attach an upload progress display if it was requested
def open_file(args, mode='r'):
f = open(args.file_name, mode)
if args.progress:
f.size = os.path.getsize(args.file_name)
f.spinner = spinner(
f"Uploading image({colour(s='b')}{args.file_name}{colour()}) \
as '{colour(s='b')}{args.image_name}{colour()}' -"
)
def read_progress(self, size):
print(
f"{next(self.spinner)}{next(progress(self.size, step=size, p=self.tell()))}", end='\r'
)
f.read = hook(f.read, read_progress)
return f
# Attach a callback to be executed whenever this method is called
# Note, callback args must match method being hooked
def hook(oldfunc, hookfunk):
def merged(self, *args, **kwargs):
hookfunk(self, *args, **kwargs)
return oldfunc(*args, **kwargs)
return MethodType(merged, oldfunc.__self__)
# A spinner with a message, use `next()` to get the next frame
def spinner(msg: str):
template = f"{colour(fg='p', s='b')}{'{}'}{colour()} {msg}"
while True:
for spin in '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏':
yield template.format(spin)
# Generate a progress bar, use `next()` to get the next progress
def progress(end: int, max_col=80, step=1024, p=1):
template = f"[{colour(fg='c', s='b')}{'{}'}{colour(fg='w')}{'{}'}{colour()}|{'{}'}]"
while (p <= end):
bar = '▇' * int(max_col * p/(end-1))
togo = '▇' * int(max_col - len(bar))
perc = "%6.2f %%" % (p/(end-1)*100)
yield template.format(bar, togo, perc)
p += step
# Set the colour of the next segment of text
def colour(fg='w', bg='b', s='n'):
return ESCAPE['t'].format(
s=ESCAPE['s'][s],
fg=ESCAPE['c']['fg'][fg],
bg=ESCAPE['c']['bg'][bg]
)
P.s。我意识到每次都重新创建进度条效率不高,但我不知道每次更改 step
值的任何其他方法,因为上传速度不是恒定的,我仍然需要它与 next
一起在其他地方使用。
我正在尝试使用 function I came up with,这样我就可以添加一个进度条显示文件已读取的数量,但是当我这样做时:
file_path = 'file'
f = open(file_path, 'rb')
file_size = os.path.getsize(file_path)
def new_readline(self, size=-1):
print(self.tell(), '/', file_size)
f.read = hook(new_readline, f.read)
如果我尝试用 f.readlines()
读取文件的行,它不会显示任何内容,它只会在我使用 f.readline()
.
即使我挂了f.read
我还是一无所获
那么,我可以挂钩的所有数据读取方法调用的通用方法是什么(不一定是 readline 方法,只是它们都调用自己的东西)?
最后我不得不将钩子附加到 read()
方法,但它有效!
无论如何,这里有完整的代码供感兴趣的人使用:
from types import MethodType
import os
ESCAPE = {
'c': { # colours
'fg': { # foreground
'b': '30', # black
'r': '31', # red
'g': '32', # green
'y': '33', # yellow
'u': '34', # blue
'p': '35', # purple
'c': '36', # cyan
'w': '37', # white
},
'bg': { # background
'b': '40', # black
'r': '41', # red
'g': '42', # green
'y': '43', # yellow
'u': '44', # blue
'p': '45', # purple
'c': '46', # cyan
'w': '47', # white
}
},
's': { # style
'n': '0', # none
'b': '1', # bold
'u': '2', # underline
'n1': '3', # negative1
'n2': '5', # negative2
},
't': '3[{s};{fg};{bg}m', # template
'util': {
'hide': '3[?25l',
'show': '3[?25h',
'go_up': '3[{}A',
'go_down': '3[{}B',
'erase_line': '3[K',
}
}
# Open a file but attach an upload progress display if it was requested
def open_file(args, mode='r'):
f = open(args.file_name, mode)
if args.progress:
f.size = os.path.getsize(args.file_name)
f.spinner = spinner(
f"Uploading image({colour(s='b')}{args.file_name}{colour()}) \
as '{colour(s='b')}{args.image_name}{colour()}' -"
)
def read_progress(self, size):
print(
f"{next(self.spinner)}{next(progress(self.size, step=size, p=self.tell()))}", end='\r'
)
f.read = hook(f.read, read_progress)
return f
# Attach a callback to be executed whenever this method is called
# Note, callback args must match method being hooked
def hook(oldfunc, hookfunk):
def merged(self, *args, **kwargs):
hookfunk(self, *args, **kwargs)
return oldfunc(*args, **kwargs)
return MethodType(merged, oldfunc.__self__)
# A spinner with a message, use `next()` to get the next frame
def spinner(msg: str):
template = f"{colour(fg='p', s='b')}{'{}'}{colour()} {msg}"
while True:
for spin in '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏':
yield template.format(spin)
# Generate a progress bar, use `next()` to get the next progress
def progress(end: int, max_col=80, step=1024, p=1):
template = f"[{colour(fg='c', s='b')}{'{}'}{colour(fg='w')}{'{}'}{colour()}|{'{}'}]"
while (p <= end):
bar = '▇' * int(max_col * p/(end-1))
togo = '▇' * int(max_col - len(bar))
perc = "%6.2f %%" % (p/(end-1)*100)
yield template.format(bar, togo, perc)
p += step
# Set the colour of the next segment of text
def colour(fg='w', bg='b', s='n'):
return ESCAPE['t'].format(
s=ESCAPE['s'][s],
fg=ESCAPE['c']['fg'][fg],
bg=ESCAPE['c']['bg'][bg]
)
P.s。我意识到每次都重新创建进度条效率不高,但我不知道每次更改 step
值的任何其他方法,因为上传速度不是恒定的,我仍然需要它与 next
一起在其他地方使用。