简体   繁体   English

Python 3 UnboundLocalError:在try语句中赋值之前引用的局部变量

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

I'm trying to make a program that handles RSA encryption and decryption for sending messages using the rsa library.我正在尝试制作一个程序来处理 RSA 加密和解密,以便使用 rsa 库发送消息。 Currently I'm implementing it to use only 1 key pair, but it'll be changed later on.目前我正在实施它以仅使用 1 个密钥对,但稍后会更改。 I'm having some trouble with the logic to check whether the files that store the keys exist or not.我在检查存储密钥的文件是否存在的逻辑上遇到了一些问题。 The logic for these functions looks like so:这些函数的逻辑如下所示:

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()

The main() function, specifically the try: except: statement is where my problem resides. main() function,特别是try: except:语句是我的问题所在。 The error I'm getting is builtins.NameError: name 'pubkey' is not defined .我得到的错误是builtins.NameError: name 'pubkey' is not defined I've tried declaring the variables as global, which is what other answers suggested, but that didn't work for me, or I'm doing it wrong.我尝试将变量声明为全局变量,这是其他答案所建议的,但这对我不起作用,或者我做错了。

Thanks for the help.谢谢您的帮助。 Sorry for the noob question.对不起菜鸟问题。

EDIT: So, that solved my first problem.编辑:所以,这解决了我的第一个问题。 However, now when I use the try/except statement, it tries to call the variables, which have a value of None , even though I'm assigning them a value using the functions.但是,现在当我使用try/except语句时,它会尝试调用值为None的变量,即使我使用函数为它们分配了值。 The stack trace is堆栈跟踪是

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'

Even if you declare a variable as global inside a function, you still need to initialize it, or in the global scope or while declaring them. 即使您将变量声明为函数内部的全局变量,仍然需要在全局范围内或在声明变量时对其进行初始化。

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()

You should declare the variables pubkey and privkey outside the function genKeys() and then the error should vanish. 您应该在genKeys()函数外部声明变量pubkey和privkey,然后错误应消失。 This is my first post, I hope to be helpful. 这是我的第一篇文章,希望对您有所帮助。 Regards. 问候。

Your problem is here: 您的问题在这里:

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

Python logical operators return the last inspected value, not True or False. Python逻辑运算符返回最后检查的值,而不是True或False。 That value was a file object from the open command is not equal to True. 该值是来自open命令的file对象,不等于True。 You could check the files for existence with os.path.isfile and skip the try/except block completely. 您可以使用os.path.isfile检查文件是否存在,并完全跳过try / except块。 Or you could just try the actual read the in the try block, like so 或者您可以尝试在try块中实际读取,就像这样

(slimmed down for demo) (为演示而精简)

# 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()

Copying the code of the other answer and with the change to check for globals() instead of overwriting None variables at every function call.复制另一个答案的代码并进行更改以检查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()

This is untested.这是未经测试的。 I did that for local variables instead where a local connection object was closed in the finally block.我对局部变量执行此操作,而不是在 finally 块中关闭了本地连接 object。 For that, I did not even have to set the objects as None at any time since I checked for the connection object to be in globals() before closing it.为此,我什至不必在任何时候将对象设置为None ,因为我在关闭它之前检查了连接 object 是否在globals()中。 The error was gone.错误消失了。

In this code, however, you do not just close objects, you overwrite them instead, both in the try and in the except block.然而,在这段代码中,您不仅关闭了对象,还覆盖了它们,无论是在try块中还是在except块中。 Therefore, I just guess that you need to make the None objects at first loading time.因此,我只是猜测您需要在第一次加载时创建None对象。 If this trick works for global variables as well, this will be the only code that does not overwrite global objects with None every time the function gets called, but only if the variables are touched the first time.如果这个技巧也适用于全局变量,那么这将是唯一不会在每次调用 function 时用None覆盖全局对象的代码,但前提是第一次接触到变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 UnBoundLocalError:赋值之前引用的局部变量(Python) - UnBoundLocalError: local variable referenced before assignment (Python) python - UnboundLocalError:分配前引用的局部变量 - python - UnboundLocalError: local variable referenced before assignment Python-UnboundLocalError:分配前引用的局部变量 - Python - UnboundLocalError: local variable referenced before assignment` Python UnboundLocalError:分配前引用了局部变量 - Python UnboundLocalError: local variable referenced before assignment Python | 如果变量:| UnboundLocalError:赋值前引用的局部变量&#39;variable&#39; - Python | if variable: | UnboundLocalError: local variable 'variable' referenced before assignment if 语句后的“UnboundLocalError:赋值前引用的局部变量” - "UnboundLocalError: local variable referenced before assignment" after an if statement UnboundLocalError:在python闭包中赋值之前引用的局部变量 - UnboundLocalError: local variable referenced before assignment in python closure Python(3.3):UnboundLocalError:分配前已引用局部变量 - Python (3.3): UnboundLocalError: local variable referenced before assignment Python 分裂问题 UnboundLocalError:分配前引用了局部变量“e” - Python Splinter issue UnboundLocalError: local variable 'e' referenced before assignment UnboundLocalError:分配前引用的局部变量“转” - python - UnboundLocalError: local variable 'turn' referenced before assignment - python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM