Python 3 UnboundLocalError: local variable referenced before assignment in try statement

Python 3 UnboundLocalError: local variable referenced before assignment in try statement

我正在尝试制作一个程序来处理 RSA 加密和解密,以便使用 rsa 库发送消息。目前我正在实施它以仅使用 1 个密钥对,但稍后会更改。我在检查存储密钥的文件是否存在的逻辑上遇到了一些问题。这些函数的逻辑如下所示:

import rsa

################################################
keySize = 256
################################################


def genKeys():
    pubkey, privkey = rsa.newkeys(keySize)

    with open("public.pem", "w") as pub:
        pub.write(str(pubkey))

    with open("private.pem", "w") as priv:
        priv.write(str(privkey))

    return pubkey, privkey

def readKeys():

      with open("private.pem", "r") as priv:
          keydata = priv.read()
          privkey = rsa.PrivateKey.load_pkcs1(keydata)
          print(privkey)

      with open("public.pem", "r") as pub:
          keydata = pub.read()
          pubkey = rsa.PublicKey.load_pkcs1(keydata)
          print(pubkey)
      return pubkey, privkey




def send(message, pubkey):
    message = message.encode('utf-8')
    crypto = rsa.encrypt(message, pubkey)
    return crypto

def recv(crypto, privkey):
    message = rsa.decrypt(crypto, privkey)
    message = message.decode('utf-8')
    return message

def main():
    global pubkey, privkey
    try:
        if (open("private.pem", "r") and open("public.pem", "r")) == True:

            pubkey, privkey = readKeys()

    except:
        (pubkey, privkey) = genKeys()

    cryptMessage = send('hello world', pubkey)
    print(cryptMessage)
    print(recv(cryptMessage, privkey))

if __name__ == "__main__":
    main()

main() 函数,特别是 try: except: 语句是我的问题所在。我得到的错误是 builtins.NameError: name 'pubkey' is not defined。我试过将变量声明为全局变量,这是其他答案所建议的,但这对我不起作用,或者我做错了。

感谢您的帮助。对不起,菜鸟问题。

编辑: 所以,这解决了我的第一个问题。但是,现在当我使用 try/except 语句时,它会尝试调用值为 None 的变量,即使我使用函数为它们赋值也是如此。堆栈跟踪是

File "", line 61, in <module>
  main()
File "", line 56, in main
  cryptMessage = send('hello world', pubkey)
File "", line 37, in send
  crypto = rsa.encrypt(message, pubkey)
File "/usr/local/lib/python3.6/dist-packages/rsa/pkcs1.py", line 169, in encrypt
  keylength = common.byte_size(pub_key.n)

builtins.AttributeError: 'NoneType' object has no attribute 'n'

即使您在函数内将变量声明为全局变量,您仍然需要对其进行初始化,或者在全局范围内或在声明它们时进行初始化。

import rsa

################################################
keySize = 256
################################################

# DECLARATION IN GLOBAL SCOPE
pubkey = None
privkey = None

def genKeys():
    pubkey, privkey = rsa.newkeys(keySize)

    with open("public.pem", "w") as pub:
        pub.write(str(pubkey))

    with open("private.pem", "w") as priv:
        priv.write(str(privkey))

    return pubkey, privkey

def readKeys():

      with open("private.pem", "r") as priv:
          keydata = priv.read()
          privkey = rsa.PrivateKey.load_pkcs1(keydata)
          print(privkey)

      with open("public.pem", "r") as pub:
          keydata = pub.read()
          pubkey = rsa.PublicKey.load_pkcs1(keydata)
          print(pubkey)
      return pubkey, privkey




def send(message, pubkey):
    message = message.encode('utf-8')
    crypto = rsa.encrypt(message, pubkey)
    return crypto

def recv(crypto, privkey):
    message = rsa.decrypt(crypto, privkey)
    message = message.decode('utf-8')
    return message

def main():
    # DECLARATION INSIDE THE FUNCTION
    global pubkey, privkey; pubkey = privkey = None
    try:
        if (open("private.pem", "r") and open("public.pem", "r")) == True:

            pubkey, privkey = readKeys()

    except:
        (pubkey, privkey) = genKeys()

    cryptMessage = send('hello world', pubkey)
    print(cryptMessage)
    print(recv(cryptMessage, privkey))

if __name__ == "__main__":
    main()

您应该在函数外声明变量 pubkey 和 privkey genKeys(),然后错误应该消失。 这是我的第一个post,希望对你有所帮助。 问候。

您的问题在这里:

if (open("private.pem", "r") and open("public.pem", "r")) == True:

Python 逻辑运算符 return 最后检查的值,不是 True 或 False。该值是来自打开命令的 file 对象不等于 True。您可以使用 os.path.isfile 检查文件是否存在并完全跳过 try/except 块。或者你可以尝试在 try 块中实际读取,就像这样

(为了演示而精简)

# dummys for test...

def readKeys():
    print('try read')
    return open('public.pem').read(), open('private.pem').read()

def genKeys():
    print('try write')
    open('public.pem','w').write('foo')
    open('private.pem','w').write('bar')
    return 'foo', 'bar'


def main():
    global pubkey, privkey
    try:
        pubkey, privkey = readKeys()
    except:
        (pubkey, privkey) = genKeys()


if __name__ == "__main__":
    main()