改进版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) 会显示提示字符串, 关闭键盘的屏幕反馈, 然后读取密码. 如果提示参数省略, 那么 ...
随机推荐
- Linux OpenGL 实践篇-5 纹理
纹理 在之前的实践中,我们所渲染的物体的表面颜色都是纯色或者根据顶点位置计算出的一个颜色,这种方式在表现物体细节方面是比较吃资源的,因为我们每增加一个细节,我们就需要定义更多的顶点及其属性.所以美术人 ...
- Animations in UWP Community Toolkit - Overview
概述 UWP Community Toolkit 中有一个 Animations 的集合,它们可以帮助开发者实现很多的动画,本篇我们先来看一下 Animations 的功能都有哪些,再后面会针对每一 ...
- 初探Javascript之DOM
DOM对象(文档对象模型) HTML DOM 是 W3C 标准(是 HTML 文档对象模型的英文缩写,Document Object Model for HTML).HTML DOM 定义了用于 HT ...
- leetcode 448. Find All Numbers Disappeared in an Array -easy (重要)
题目链接: https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/description/ 题目描述: Give ...
- C#利用微软企业库Enterprise Library配置mysql数据库
在C#项目中,很多时候到要用到Enterprise Library.这里只是用一个很简单的小例子来演示一下Enterprise Library在VS2010中操作MySQL数据库的流程. 1,利用En ...
- thymeleaf-迭代
迭代 1.迭代基础 要在/WEB-INF/templates/product/list.html页面中显示产品,将使用一个表格.都将显示在一行(一个<tr>元素),所以对于我们的模板,我们 ...
- 安卓开发JAVA基础之初识JAVA
JAVA的一大特点------不依赖平台 JAVA在平台之上提供了一个JAVA运行环境(Java Runtime Environment, JRE),该环境由Java虚拟机(Java Virtua ...
- BZOJ3129: [Sdoi2013]方程
拓展Lucas+容斥原理 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cs ...
- 51nod 1981 如何愉快地与STL玩耍
Description 驴蛋蛋在愉快地与STL玩耍 突然间小A跳了出来对驴蛋蛋说,看你与STL玩的很开心啊,那我给你一个大小为N的vector,这个vector上每个位置上是一个set, 每次我会在闭 ...
- hdu4549(费马小定理 + 快速幂)
M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = a F[1] = b F[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n ...