[英]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.