将raw_input与JSON键值对匹配

时间:2014-08-27 02:59:21

标签: python json unicode match raw-input

import getpass
import json

class LogInNow(object):

    def __init__(self, file):
        self.file = json.load(open("password.txt"))

    def authenticate(self):
        self.username = raw_input("Enter Username> ")
        self.password = getpass.getpass("Enter Password> ")
        for k, v in self.file:
            if k == self.username and v == self.password:
                print "It worked"
            else:
                print "Fail"

go = LogInNow("password.txt")
go.authenticate()

一个单独的模块使用json.dump将两个输入写入password.txt

当我:

>>> import login

我明白了:

{u'go': u'go'}

我读了“你'是unicode,是好的,必须保持。

我可以在self.username之前连接你,并拆分值来添加引号,但这会破坏目的。

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

u不是字符串的一部分,不仅仅是引号。 u'go'就是Python如何表示值为go的Unicode字符串。你不需要"连接u"或类似的东西。

raw_input将返回'go',而不是u'go',因为它在编码的字节字符串中读取。但是在Python 2.x中,如果你比较这两个字符串,它们仍然是相同的。试试吧:

>>> 'go' == u'go'
True

所以,这里没有问题。

但是,只要您开始处理非ASCII用户名或密码,那么 就会出现问题。您需要使用输入的编码调用decode来自用户的值,如下所示:

>>> self.username = raw_input("Enter Username> ").decode(sys.stdin.encoding)

这有点笨拙,但是嘿,Unicode在Python 2.x中很笨拙,这就是Python 3.x被发明的原因。


但是,您的代码中存在一个错误,可能会导致您遇到的任何问题:

for k, v in self.file:

循环遍历字典时,循环显示,而不是其键值对。因此,每个用户名都会解压缩到kv。如果您的任何用户名长度不超过2个字符,则会获得ValueError: too many values to unpack。但是因为您恰好只有一个用户名,并且恰好是2个字符长,u'go'会被解压缩到u'g'u'o'。因此,不是将用户名与gogo的密码进行比较,而是最终将用户名与g和密码o进行比较,而不是for k, v in self.file.items():。匹配。

如果要迭代键值对,请使用items


但是你通常不想通过字典for k, v in self.file: if k == self.username and v == self.password: print "It worked" else: print "Fail" 来搜索它。 dict的全部意义在于你可以立即查看。而不是:

if self.password == self.file.get(self.username):
    print "It worked"
else:
    print "Fail"

......就这样做:

try:
    if self.password == self.file[self.username]:
        print "It worked"
    else:
        print "That's the wrong password, you evil hacker"
except KeyError:
    print "I've never heard of you"

或者,如果你想区分"错误的密码"来自"未知用户":

{{1}}