首页 > 解决方案 > Python中readline、readlines、read等常用接口是什么

问题描述

我正在尝试使用我想出的功能,所以我可以添加一个进度条显示文件已读取多少,但是当我这样做时:

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 方法,只是他们都调用 self 的东西)?

标签: pythonfilemethods

解决方案


最后我不得不将钩子附加到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': '\033[{s};{fg};{bg}m', # template 
    'util': {
        'hide': '\033[?25l',
        'show': '\033[?25h',
        'go_up': '\033[{}A',
        'go_down': '\033[{}B',
        'erase_line': '\033[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]
    )


Ps 我意识到每次都重新创建进度条效率不高,但我不知道有什么其他方法可以step每次更改值,因为上传速度不是恒定的,我仍然需要它来next使用在其他地方。


推荐阅读