[英]UnBoundLocalError: local variable referenced before assignment (Python)
[英]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()
function,特别是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()
您应该在genKeys()
函数外部声明变量pubkey和privkey,然后错误应消失。 这是我的第一篇文章,希望对您有所帮助。 问候。
您的问题在这里:
if (open("private.pem", "r") and open("public.pem", "r")) == True:
Python逻辑运算符返回最后检查的值,而不是True或False。 该值是来自open命令的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()
复制另一个答案的代码并进行更改以检查globals()
而不是在每次 function 调用时覆盖None
变量。
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;
if 'pubkey' not in globals() or 'privkey' not in in globals():
pubkey = privkey = None
try:
if (open("private.pem", "r") and open("public.pem", "r")) == True:
if 'pubkey' in globals() and 'privkey' in globals():
pubkey, privkey = readKeys()
except:
if 'pubkey' in globals() and 'privkey' in globals():
(pubkey, privkey) = genKeys()
if 'pubkey' in globals() and 'privkey' in globals():
cryptMessage = send('hello world', pubkey)
print(cryptMessage)
print(recv(cryptMessage, privkey))
if __name__ == "__main__":
main()
这是未经测试的。 我对局部变量执行此操作,而不是在 finally 块中关闭了本地连接 object。 为此,我什至不必在任何时候将对象设置为None
,因为我在关闭它之前检查了连接 object 是否在globals()
中。 错误消失了。
然而,在这段代码中,您不仅关闭了对象,还覆盖了它们,无论是在try
块中还是在except
块中。 因此,我只是猜测您需要在第一次加载时创建None
对象。 如果这个技巧也适用于全局变量,那么这将是唯一不会在每次调用 function 时用None
覆盖全局对象的代码,但前提是第一次接触到变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.