180120 login 用户登录的代码

import getpass    #导入getpass 内置模块

#定义用户名、密码列表
allow_user_list = []    #定义一个空列表 ,名字是allow...
pass_list = []        #同上,空列表
#定义被锁定列表
deny_user_list = []      #同上

#读取用户名密码文件并输出到字典中
with open('allow_user','r') as f:  #关于with open 在下面有详细解释。
    for line in f.readlines():    #再度看到生成器的for计数循环
        allow_user_list.append(line.strip('
').split('|')[0])    #往列表添加
        pass_list.append(line.strip('
').split('|')[1])        #同上
user_pass = dict(zip(allow_user_list,pass_list))            #定义一个变量 

#读取被锁定用户文件并输出到列表中
with open('deny_user','r') as f:
    for line in f.readlines():
        deny_user_list.append(line.strip('
'))      #line.strip 大概是去掉空格和空行

#初始化标记
flag_num = 0

#登录开始,循环
while flag_num < 3:
    #输入登录用户名
    username = input('请输入用户名:')
    #输入登录密码
    #password = getpass.getpass('请输入密码:')   #这大概是首次在代码块中看到getpass,这个getpass模块还有一个getuser的函数。
    password = input('请输入密码:')         #获取用户的输入的密码,input内置夯实
    #当用户名密码都正确并且用户没被锁定,打印欢迎界面并退出程序
    if username in user_pass and password == user_pass[username] and username not in deny_user_list:    #这里有个if...in...and...==...and...not in..
        print ('''
        登录成功
        欢迎你,%s
        ''' % username)
        break
    #当用户名密码都正确但用户已被锁定,打印用户已被锁定
    elif username in user_pass and password == user_pass[username] and username in deny_user_list:    #同上
        print ('该用户已被锁定')
        flag_num += 1
    #当用户名不存在时,打印用户名不存在
    elif username not in user_pass:
        print ('该用户不存在')
        flag_num += 1
    #当用户存在并且没被锁定,但密码错误,打印密码错误
    else:
        print ('密码错误')
        flag_num +=1
#输入错误三次后用户被锁定
else:
    if username not in deny_user_list and username in allow_user_list:
        with open('deny_user','a') as f:
            f.write(username+'
')
        print ('错误输入三次,该用户已被锁定')
    elif username in allow_user_list:
        print ('错误输入三次,该用户已是被锁定状态')
    else:
        print ('错误输入三次,该用户不存在无法锁定')    #疑问?哪里看到了3次的限制代码语句??

读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。

读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。

读文件

要以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符:

>>> f = open('/Users/michael/test.txt', 'r')

标示符'r'表示读,这样,我们就成功地打开了一个文件。

如果文件不存在,open()函数就会抛出一个IOError的错误,并且给出错误码和详细的信息告诉你文件不存在:

>>> f=open('/Users/michael/notfound.txt', 'r')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/Users/michael/notfound.txt'

如果文件打开成功,接下来,调用read()方法可以一次读取文件的全部内容,Python把内容读到内存,用一个str对象表示

>>> f.read()
'Hello, world!'

最后一步是调用close()方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的:

>>> f.close()

由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来实现:

复制代码
try:
    f = open('/path/to/file', 'r')
    print(f.read())
finally:
    if f:
        f.close()
复制代码

但是每次都这么写实在太繁琐,所以,Python引入了with语句来自动帮我们调用close()方法

with open('/path/to/file', 'r') as f:
    print(f.read())

这和前面的try ... finally是一样的,但是代码更佳简洁,并且不必调用f.close()方法。

调用read()会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用read(size)方法,每次最多读取size个字节的内容。另外,调用readline()可以每次读取一行内容,调用readlines()一次读取所有内容并按行返回list。因此,要根据需要决定怎么调用。

如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,调用readlines()最方便:

for line in f.readlines():
    print(line.strip()) # 把末尾的'
'删掉

写文件

写文件和读文件是一样的,唯一区别是调用open()函数时,传入标识符'w'或者'wb'表示写文本文件或写二进制文件:

>>> f = open('/Users/michael/test.txt', 'w')
>>> f.write('Hello, world!')
>>> f.close()

你可以反复调用write()来写入文件,但是务必要调用f.close()来关闭文件。当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用with语句来得保险:

with open('/Users/michael/test.txt', 'w') as f:
    f.write('Hello, world!')

要写入特定编码的文本文件,请给open()函数传入encoding参数,将字符串自动转换成指定编码

=======================================================================

描述

Python strip() 方法用于移除字符串头尾指定的字符(默认为空格)。

语法

strip()方法语法:

str.strip([chars]);

line.strip()会把'\n'(空行)替换为


-------------------------------------------------------------------------------------

getpass模块

昨天跟学弟吹牛b安利Python标准库官方文档的时候偶然发现了这个模块。仔细一看内容挺少的,只有两个主要api,就花了点时间阅读了一下源码,感觉挺实用的,在这安利给大家。


getpass.getpass(prompt=’Password: ‘, stream=None)

调用该函数可以在命令行窗口里面无回显输入密码。参数prompt代表提示字符串,默认是’Password: ‘。在Unix系统中,stream默认为当前控制的终端。在Windows系统里stream参数会被忽略掉,默认使用stdin。如果无法正常使用getpass,会打印错误信息,然后模块会使用有回显的模式读取数据。

>>> import getpass
>>> passwd = getpass.getpass()
Password:
>>> print(passwd)
ganziqim
  • 1
  • 2
  • 3
  • 4
  • 5

getpass.getuser()

返回当前用户名。这个函数会按顺序检查环境变量LOGNAME, USER, LNAME和USERNAME。返回第一个非空的值。如果检查不到非空的值,模块会尝试导入pwd模块,如果系统支持pwd模块,会返回通过pwd模块获取的用户名,否则报错。

>>> getpass.getuser()
'ganzi'
  • 1
  • 2

一些细节

  1. getpass模块内部其实实现了unix_getpass、win_getpass和fallback_getpass三个函数。在模块被导入之后会首先对用户使用的系统进行检查,将相应的函数赋值给getpass。如果检查失败,则将fallback_getpass赋值给getpass。

  2. win_getpass使用msvcrt.getwch()获取无回显输入。

  3. fallback_getpass不仅在一开始检查系统的时候被调用,当另外两个函数出现错误的时候也会调用它。而调用了fallback_getpass又会先打印错误信息,然后再调用模块内部的_raw_input函数进行有回显的输入读取。

这个是写在模块底部的系统检查代码:

try:
    import termios
    termios.tcgetattr, termios.tcsetattr
except (ImportError, AttributeError):
    try:
        import msvcrt
    except ImportError:
        getpass = fallback_getpass
    else:
        getpass = win_getpass
else:
    getpass = unix_getpass
  • 总结:getpass模块只有不到200行代码(包括注释和模块文档),getuser的主要代码更是只有短短7行,内部实现非常简单。但模块内部有很多处理异常情况的代码,很多细节没办法在博客里面展开细说,说了显得啰嗦,不像是笔记。所以建议有兴趣的读者花点时间阅读一下源码,能对模块的细节有更充分的理解。
 
原文地址:https://www.cnblogs.com/cputn/p/8322396.html