首页 > 编程语言 >如何绕过Python readline的Tab-补全

如何绕过Python readline的Tab-补全

时间:2024-02-04 10:32:59浏览次数:30  
标签:__ 补全 stdout Python self sys Tab name

在 Python 中,readline 模块提供了一个交互式的命令行输入接口,其中的 Tab 补全是指用户在输入时按下 Tab 键,系统会自动尝试完成当前输入的命令或路径。

Tab 补全的主要功能是帮助用户更快速、更准确地输入命令或路径,尤其是当有很多可能的选项时。下面我将用详细的步骤来说明 Tab 补全的具体作用:

如何绕过Python readline的Tab-补全_爬虫

1、问题背景

在一个使用 Python 的应用程序中,我们使用了 cmd.Cmd 模块来构建命令行界面,而它的选项卡自动补全功能(Tab-completion)也能正常运行。现在,我们想要在原先的基础上替换 sys.stdout 对象,以便捕获正在被写入的信息。

为了替换 sys.stdout 对象,我们创建了以下 Std 类:

class Std(object):
    def __getattribute__(self, name):
        if name in ('__getattribute__', '__setattr__'):
            return object.__getattribute__(self, name)
        else:
            return getattr(sys.__stdout__, name)

    def __setattr__(self, name, value):
        setattr(sys.__stdout__, name, value)

通过这个类我们可以把对 Std 类的任何 getset 操作重定向到真实的 sys.__stdout__ 对象。比如,调用 sys.stdout.fileno() 仍然会返回文件描述符 1。

然而,当替换 sys.stdout 对象之后,cmd.Cmd 的自动补全功能却不再起作用了。为了解决这个问题,我们尝试使用 file 进行继承(stdout 本身是一个文件对象)。

class Std(file):
    def __init__(self):
        pass
    def __getattribute__(self, name):
        if name in ('__getattribute__', '__setattr__'):
            return object.__getattribute__(self, name)
        else:
            return getattr(sys.__stdout__, name)

    def __setattr__(self, name, value):
        setattr(sys.__stdout__, name, value)

但是,这次尝试却又导致了以下错误:

ValueError: I/O operation on closed file

于是,我们尝试直接阅读 Readline 的源码来理解其中的问题。然而,Readline 的源码并不容易理解。

2、解决方案

虽然我们并不完全知道为什么替换 sys.stdout 对象会导致问题,但有一种方法可以解决这个问题:直接将我们自己的文件对象传给 cmd.Cmd 构造函数。

import sys, cmd

class Std(object):
    def __getattribute__(self, name):
        if name in ('__getattribute__', '__setattr__'):
            return object.__getattribute__(self, name)
        else:
            return getattr(sys.__stdout__, name)

    def __setattr__(self, name, value):
        setattr(sys.__stdout__, name, value)

class HelloWorld(cmd.Cmd):
    FRIENDS = [ 'Alice', 'Adam', 'Barbara', 'Bob' ]

    def do_greet(self, person):
        "Greet the person"
        if person and person in self.FRIENDS:
            greeting = 'hi, %s!' % person
        elif person:
            greeting = "hello, " + person
        else:
            greeting = 'hello'
        print greeting

    def complete_greet(self, text, line, begidx, endidx):
        if not text:
            completions = self.FRIENDS[:]
        else:
            completions = [f for f in self.FRIENDS
                           if f.startswith(text)]
        return completions

    def do_EOF(self, line):
        return True

if __name__ == '__main__':

    HelloWorld(stdout=Std()).cmdloop()

这种做法更好,因为它能确保只捕获 cmd 实例所产生的输出。值得注意的是,我们传入的文件对象也能作为 cmd 实例中的一个 stdout 属性使用。

在上述示例中,当用户输入部分水果名称(例如 'app')并按下 Tab 键时,readline 将自动补全为匹配的选项,如 'apple'。如果有多个匹配项,用户可以继续按下 Tab 键以在可选项之间进行循环。

通过设置 readline 的补全函数和绑定 Tab 键的行为,可以在交互式 Python 环境中实现类似于 Bash 等 shell 的 Tab 补全功能,提高用户的输入效率。

通过上面的案例是不是觉得很神奇?通过小小的改动居然可以达到意想不到的效果,就问牛不牛。当然如果有任何技术性的疑惑,可以评论区留言一起讨论。

标签:__,补全,stdout,Python,self,sys,Tab,name
From: https://blog.51cto.com/u_13488918/9578241

相关文章

  • python操作yaml
     补充:yaml语法详见:yaml语法 yaml应用场景1、保存自动化测试数据2、保存自动化测试中的关联数据  安装yaml模块pipinstallpyyaml==5.4.1 读取yaml数据读取数据:load()或者full_load(),返回一个对象用例数据:case.yaml-caseId:1apiName:registerdescribe:注册url:......
  • 系统环境变量,python包导入的路径搜索机制,PYTHONPATH,sys.path
    系统环境变量的定义通过在环境变量里面加入所有软件的安装路径,当我们想运行某一软件时双击其快捷方式,此时,计算机除了在其当前目录下寻找该软件的.exe文件外(windows系统),还会在环境变量中搜索软件的路径,找到,运行。综上,Windows中的环境变量,当要求系统运行一个程序而没有告诉它程序......
  • VS Code 便携模式(Portable Mode)的制作
    VisualStudioCode支持便携式模式。此模式使VSCode创建和维护的所有数据都位于其自身附近,因此可以跨环境移动。此模式还提供了一种设置VSCode扩展的安装文件夹位置的方法,对于阻止在企业环境将扩展安装在WindowsAppData文件夹中非常有用。Windows的ZIP下载、Linux......
  • [MY-013183] [InnoDB] Assertion failure: dict0dict.cc:1869:table->get_ref_count()
    背景:执行altertableTABLE_NAMEdroppartitionPART_NAME;时执行过程中执行了ctrl+c导致mysql服务器崩溃自动重启。mysql错误日志内容:2024-02-02T10:30:32.424737+08:00460639464[ERROR][MY-013183][InnoDB]Assertionfailure:dict0dict.cc:1869:table->get_ref_count......
  • Python 基于pymongo操作Mongodb学习总结
    实践环境Python3.6.4pymongo4.1.1pymongo-3.12.3-cp36-cp36m-win_amd64.whl下载地址:https://pypi.org/simple/pymongo/代码实践#!/usr/bin/envpython#-*-coding:utf-8-*-importdatetimeimportrandomimportpymongofrompymongoimportMongoClientfrombson.objecti......
  • Python elasticsearch-py类库基础用法
    实践环境https://pypi.org/project/elasticsearch/pipinstallelasticsearch==7.6.0离线安装包及依赖包下载地址:https://files.pythonhosted.org/packages/f5/71/45d36a8df68f3ebb098d6861b2c017f3d094538c0fb98fa61d4dc43e69b9/urllib3-1.26.2-py2.py3-none-any.whl#sha256=d8ff9......
  • Python 机器学习 K-近邻算法 鸢尾花种类预测
    ​ K-近邻算法(K-NearestNeighbors,KNN)是一种简单而强大的机器学习算法,适用于分类和回归任务。可以使用scikit-learn库的KNN算法来预测鸢尾花(Iris)的种类。鸢尾花数据集是机器学习领域中常用的一个数据集,包含了150个鸢尾花样本,每个样本有四个特征:萼片长度、萼片宽度、花瓣长度......
  • BeautifulSoup爬虫库应用——Python 页面解析
    爬虫技术作为信息搜集的重要手段,在大数据时代发挥着至关重要的作用。通过网络爬虫,可以高效地从各种在线源头获取大规模、多样化的数据,为大数据分析和应用提供了必要的原始材料。首先,爬虫使得大数据的采集更为全面和及时。网络上存在着庞大的信息资源,包括社交媒体、新闻网站、电子......
  • 工作安排-od-python
    工作安排小明每周上班都会拿到自己的工作清单,工作清单内包含n项工作,每项工作都有对应的耗时时长(单位h)和报酬,工作的总报酬为所有已完成工作的报酬之和。那么请你帮小明安排一下工作,保证小明在指定的工作时间内工作收入最大化。输入描述输入的第一行为两个正整数T,n。T代表工作......
  • Python随机波动模型Stochastic volatility,SV随机变分推断SVI分析标普500指数股票价格
    全文链接:https://tecdat.cn/?p=33809原文出处:拓端数据部落公众号随机波动模型(Stochasticvolatilitymodels)经常被客户用来对股票价格随时间的变动性进行建模。波动性(volatility)是随时间的对数收益的标准差。与假设波动性恒定不变不同,随机波动模型具有隐变量参数,可以在每个时刻......