改进版getpass库
用过Linux的都知道,尤其是进行使用包管理软件类似于apt-get这种的,密码是不回显的。在一定程度上可以保护我们的密码不被旁边的人看到,保护个人的隐私。但是很多时候,我们自己也是深受其害,因为不知道自己已经输入了几个字符了,这就有可能会让不自信的人删完,再重输入一遍。
同样的Python标准库里面有一个叫getpass的库,比较简单,针对于windows 和 Mac OS X都适配。用途也很广泛,但是唯一的缺点可能就跟上面说道的一样,不能显示已经输入了多少个字符! 这就显得很尴尬了。
那么今天就从易用性的角度出发,写一个更好用的getpass出来吧。
编程伊始
类比于一个进度条,在输入数据的时候,是不能够换行的。也就是说,提示语句只会在本行内显示。
常用的print函数末尾会自动的换行回车,所以我们不能用它了。然而sys.stdout.write则不会在后面添加额外的东西。二者正是我们想要的。但是其存在一个问题,那就是不强制输出的话,默认不输出信息,所以我们还需要强制输出一下。借助于sys.stdout.flush函数即可。
下面先来看个小例子,就很容易明白了。
def test():
import sys, time
for i in range(5):
sys.stdout.write(str(i) * (5 - i) + '\r')
sys.stdout.flush()
time.sleep(1)
运行结果如下:
正式实施
根据上面的思想,稍微动动脑筋我们就可以实现想要的功能了。代码很简单,大致如下:
# coding:utf-8
import sys, os
from time import *
reload(sys)
sys.setdefaultencoding('utf8')
# __author__ = '郭 璞'
# __date__ = '2016/10/15'
# __Desc__ = 改进版的getpass,更易用,更好用!
def getpass(prompt='', tip = 'You have typed %d characters!'):
# print the prompt to prompt user what to do
print prompt
import msvcrt
# get one charecter from terminal
cur_character = msvcrt.getch()
# the result will be out final answer!
result =''+cur_character
count = 1
# 循环的读取从控制台输入的字符数据 get character once a time from terminal
while cur_character!= '\r':
# show message at the old line with the help of the function named sys.stdout.write and sys.stdout.flush
sys.stdout.write(tip%(count)+"\r")
sys.stdout.flush()
# update the needed item
cur_character = msvcrt.getch()
result += cur_character
count += 1
# to avoid overlap the message, we'd better go to next new line.
print "\n"
# return what we really need
return result
if __name__ == '__main__':
password = getpass(prompt='\bplease input your username(there should contains no space):')
print password
运行结果,符合我们的需求,如下:
最后输出了输入结果的原因就是我们main函数里面故意输出了,具体怎么用取决于您的代码。
改进版
至于改进版,是添加了自定义delimiter需求,以及完善“中途删除操作”等。
源码
# coding:utf-8
import sys, os
from time import *
reload(sys)
sys.setdefaultencoding('utf8')
# __author__ = '郭 璞'
# __date__ = '2016/10/15'
# __Desc__ = just like getpass lib, this is also simple and easy to use. While the drawback is it's not so much pythonic in the implement of the function 'replace'.
# I am happy to hear you can join me to slove it. :)
# 改进版的getpass,更易用,更好用! 唯一的缺点就是replace函数中的实现略显粗糙,欢迎前来完善。
# show the numbers we have typed
def showByNumbers(prompt='', tip = 'You have typed %d characters!'):
# print the prompt to prompt user what to do
print prompt
import msvcrt
# get one charecter from terminal
cur_character = msvcrt.getch()
# the result will be out final answer!
result =''+cur_character
count = 1
# 循环的读取从控制台输入的字符数据 get character once a time from terminal
while cur_character!= '\r':
# show message at the old line with the help of the function named sys.stdout.write and sys.stdout.flush
sys.stdout.write(tip%(count)+"\r")
sys.stdout.flush()
# update the needed item
cur_character = msvcrt.getch()
if cur_character =="\b":
result = result[0:-1]
count -=1
else:
result += cur_character
count += 1
# to avoid overlap the message, we'd better go to next new line.
print "\n"
# return what we really need
return result
# use the constom char to replace what we typed
def replaceWithDelimiter(prompt='', delimiter = '*'):
print prompt
import msvcrt
current_character = msvcrt.getch()
count = 1
result = ''
result += current_character
# if we typed backspace key, we should update the interface right now!
delta = 0
# get a character once a time and do something if meet the backspace
while current_character!='\r':
# build the stars to show
stars = ''
for index in range(count):
stars += delimiter
for i in range(delta):
stars += ' '
sys.stdout.write(prompt + stars + "\r")
sys.stdout.flush()
# update for next loop
current_character = msvcrt.getch()
# consider the backspace key
if current_character == '\b':
count -=1
result = result[0:-1]
# for erase the extra delimiters
delta +=1
else:
result += current_character
count +=1
# it's necessary to print in a new line for avoiding overlapping
print "\n"
# return what we really need
return result
def getpass(prompt='', mode='n', tip='You have typed %d characters!', delimiter='*'):
if mode =='n':
return showByNumbers(prompt=prompt, tip=tip)
elif mode == 'r':
return replaceWithDelimiter(prompt=prompt, delimiter=delimiter)
else:
raise NameError('There are only two choice, so check your input!')
if __name__ == '__main__':
"""
Here are some useful test. And you can also do it just like this!
:)
"""
# password = getpass(prompt='\bplease input your username(there should contains no space):')
# print password
# password = replaceWithDelimiter(prompt='\bplease input your username(there should contains no space):', delimiter='')
# print password
password = getpass(prompt='\bplease input your username(there should contains no space):', mode='n')
print password
pwd = getpass(prompt='\bplease input your username(there should contains no space):', mode='r', delimiter='#')
print pwd
以数字显示

以自定义分隔符delimiter显示

如何使用?
由于博主将这个工具封装好了,而且已经上传到了pypi上面。所以大家可以很容易的下载以及安装。
下载及安装
pip install getpass2
在您的代码中使用
不出意外的话,使用下面的代码即可。
from getpass2 import getpass
......
如果,没能正常的工作,找到您的Python的site-packages,找到getpass2文件夹,将里面的getpass2.py拷贝到您的项目中即可。同样可以完美的运行。
源码下载
如果您想直接看一下源码的话,可以到博主的GitHub上直接下载。下载链接如下:
总结
本篇文章主要是介绍了完善Python标准库的一个小案例。其实并没有什么难于理解的地方。关键在于动手实践。
如果您对此有兴趣,不妨fork 或者star来一起完善一下吧。
(^__^) 嘻嘻……
改进版getpass库的更多相关文章
- 《Ansible权威指南》笔记(3)——Ad-Hoc命令集,常用模块
五.Ad-Hoc命令集1.Ad-Hoc命令集通过/usr/bin/ansible命令实现:ansible <host-pattern> [options] -v,--verbose ...
- python学习笔记——(二)循环
·密文输入引入getpass库使用getpass.getpass("password:")tips:该功能在PyCharm中不好使,只能在命令行用 ·python强制缩进,省略了大 ...
- Python学习【02】Python基础
一.Python内部执行过程 1.Python的后缀名可以是任意? print("hello,world") 保存成 .py / .txt / .sb / .aaa 都可以用在 ...
- 3rd,Python登录模拟
需求: 1. 用户输入帐号密码进行登陆 2. 用户信息保存在文件内 3. 用户密码输入错误三次后锁定用户 #导入getpass库,用于密码验证 import getpass #定义用户名.密码 _us ...
- Python在七牛云平台的应用(一)
七牛云:(引用百度的介绍)七牛云是国内领先的企业级公有云服务商,致力于打造以数据为核心的场景化PaaS服务.围绕富媒体场景,七牛先后推出了对象存储,融合CDN加速,数据通用处理,内容反垃圾服务,以及直 ...
- Python趣味实用小工具
代码地址如下:http://www.demodashi.com/demo/12918.html python 趣味实用小工具 概述 用python实现的三个趣味实用小工具: 图片转Execl工具 , ...
- 4.1、Ansible模块
ansible-doc -l 列出所有模块 ansible-doc 模块名 查看模块的help说明 ansible-doc -s module_name:获取指定模块的使用信息 ***文 ...
- python3学习笔记一
install 安装软件包download 下载安装包uninstall 卸载安装包freeze 按照req uirements 格式输出安装包,可以到其他服务器上执行pip install -r r ...
- DAY2 Python 标准库 -> Getpass 模块 -> 命令行下输入密码的方法.
getpass 模块 getpass 模块提供了平台无关的在命令行下输入密码的方法. getpass(prompt) 会显示提示字符串, 关闭键盘的屏幕反馈, 然后读取密码. 如果提示参数省略, 那么 ...
随机推荐
- MariaDB表表达式(2):CTE
本文目录: 1.非递归CTE 2.递归CTE 2.1 语法 2.2 递归CTE示例(1) 2.3 递归CTE示例(2) 2.4 递归CTE示例(3) 公用表表达式(Common Table Expre ...
- 0417 jQuery基础知识
jQuery基础知识 jQuery需要引入一个js文件,并且这个文件在所有js代码之前(包括引入的其他js文件) 基础操作(对比js): 1.找标签: js:document.getElement.. ...
- How to preview html file in our browser at sublime text?
sublime preview html.md open In Browser what should we do if we want to preview html file in our bro ...
- jdk1.7中的常量池
在探究jdk1.7中的常量池,我们可以先看看以下的这段代码 public static void main(String[] args) throws Throwable { List<Stri ...
- [APIO 2016]Gap
Description 题库链接 给你一个长度为 \(N\) 的单调递增序列 \(A\) .交互时允许你调用 MinMax(s, t, &mn, &mx) 函数,表示序列元素的值在 \ ...
- [ZJOI 2010]count 数字计数
Description 题库链接 问你 \([l,r]\) 区间内所有整数中各个数码出现了多少次. \(1\leq a\leq b\leq 10^{12}\) Solution 数位 \(DP\) . ...
- UVA1349:Optimal Bus Route Design
题意:给定一个有向带权图,找若干个环,使得每个点属于且仅属于一个环,要求使得环权值之和最小 题解:发现这题中每个点属于且仅属于一个环,这时候"仅"这种恰好的含义,让我们想到了匹配问 ...
- ●BZOJ 2007 NOI 2010 海拔
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2007 题解: 网络流.最小割.对偶图 奇妙的题 ~ 种种原因导致了高度要么为 0,要么为 1 ...
- hdu 5439(找规律)
The sequence is generated by the following scheme. 1. First, write down 1, 2 on a paper. 2. The 2nd ...
- Windows下使用notepad++对文本进行行列转换
行转列: Ctrl + F 选择替换 查找目标:填写指定的内容 替换为:\r\n 查找模式:正则表达式 单击替换或全部替换按钮 列转行: Ctrl + F 选择替换 查找目标:\r\n 替换为:不 ...