在函数内部实现'全局变量'后,未定义名称'variable'

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在函数内部实现'全局变量'后,未定义名称'variable'相关的知识,希望对你有一定的参考价值。

我正在研究我在python上的第一个程序,但是,当我遇到有关变量定义范围的问题时。以下是我的代码中有问题的示例:

def listen(topLeft, bottomRight):

    timeless = 0
    # The key combination to check
    COMBINATIONS = [
        {keyboard.Key.shift, keyboard.KeyCode(char='b')}
    ]

    # The currently active modifiers
    current = set()

    def execute():
        global topLeft,bottomRight,timeless
        print("Do Something")

        if timeless == 0:
            topLeft = mouse.position
            timeless += 1
        elif timeless == 1:
            bottomRight = mouse.position
            timeless += 1
        elif timeless >= 2:
            return False

    def on_press(key):
        global timeless
        if any([key in COMBO for COMBO in COMBINATIONS]):
            current.add(key)
            if any(all(k in current for k in COMBO) for COMBO in              COMBINATIONS):
                execute()

    def on_release(key):
        if any([key in COMBO for COMBO in COMBINATIONS]):
            current.remove(key)

    with keyboard.Listener(on_press=on_press, on_release=on_release) as     listener:
        listener.join()

基本上,一旦听众调用on_press,就会调用execute。为了传递timeless变量,我使用global标记。但是,一旦程序执行execute函数,我收到以下错误代码:NameError: name 'timeless' is not defined。任何帮助将不胜感激,因为我已经尝试了所有我能做的一切

答案

由于timeless实际上是函数listen中的局部变量,因此它不是全局变量,实际上您的错误来自于没有名为timeless的全局变量的事实。 execute需要的是将timeless(也可能是topLeftbottomRight)声明为非本地,因此它指的是包含词法范围的堆栈中的第一个绑定。

def listen(topLeft, bottomRight):

    timeless = 0
    # The key combination to check
    COMBINATIONS = [
        {keyboard.Key.shift, keyboard.KeyCode(char='b')}
    ]

    # The currently active modifiers
    current = set()

    def execute():
        # modify the local variables in listen
        nonlocal topLeft,bottomRight,timeless
        print("Do Something")

        if timeless == 0:
            topLeft = mouse.position
            timeless += 1
        elif timeless == 1:
            bottomRight = mouse.position
            timeless += 1
        elif timeless >= 2:
            return False

    ...

在全局范围定义的函数中,globalnonlocal是相同的,因为第一个包含范围是全局范围。在嵌套函数中,global直接跳到全局范围,而nonlocal一次一个地向上遍历嵌套范围。

另一答案

您在任何函数之外声明一个全局变量。您可以在函数内引用全局变量,而无需使用关键字。在为变量赋值时,只需要使用关键字global,作为指定要将值分配给全局变量而不是分配给同一名称的新局部变量的方式。 See this for examples。对于您的示例,首先在任何函数之外定义您的全局变量,然后在函数中使用它们,当您想要修改时使用global关键字:

# Global variable definitions outside of any function.
timeless = 0
topLeft = 0
bottomRight = 0

# Define the function that uses the variables.
def execute():
    print("Do Something")
    global timeless
    if timeless == 0:
        global topLeft  # modifying the global variable with this name!
        topLeft = mouse.position
        timeless += 1
    elif timeless == 1:
        global bottomRight  # modifying the global variable!
        bottomRight = mouse.position
        timeless += 1
    elif timeless >= 2:
        return False

所有这些都说,一般来说最好避免使用全局变量。您可以改为定义一个类,并使用成员属性来处理需要在多个方法中修改和引用的内容。例如,类似于:

class Listener:
    def __init__(self):
        self.timeless = 0
        self.top_left = 0
        self.bottom_right = 0

    def execute(self, mouse):  # pass some mouse object in, otherwise what's "mouse"?
        print('Do something')
        if self.timeless == 0:
            self.top_left = mouse.position
            self.timeless += 1
        elif self.timeless == 1:
            ...
另一答案
timeless = 0
topLeft = 0
bottomRight = 0
current = set()

def listen(topLeft, bottomRight):
    timeless = 0
    # The key combination to check
    COMBINATIONS = [
        {keyboard.Key.shift, keyboard.KeyCode(char='b')}
    ]
    # The currently active modifiers
    current = set()

def execute():
    print("Do Something")
    if timeless == 0:
        topLeft = mouse.position
        timeless += 1
    elif timeless == 1:
        bottomRight = mouse.position
        timeless += 1
    elif timeless >= 2:
        return False


def on_press(key):
    if any([key in COMBO for COMBO in COMBINATIONS]):
        current.add(key)
        if any(all(k in current for k in COMBO) for COMBO in COMBINATIONS):
            execute()


def on_release(key):
    if any([key in COMBO for COMBO in COMBINATIONS]):
        current.remove(key)

以上是关于在函数内部实现'全局变量'后,未定义名称'variable'的主要内容,如果未能解决你的问题,请参考以下文章

Python函数:全局变量和局部变量匿名函数lambda递归函数

全局变量报错:UnboundLocalError: local variable 'l' referenced before assignment

全局变量报错:UnboundLocalError: local variable 'l' referenced before assignment

PHP中如何定义全局数组?

python函数2_闭包和装饰器

作用域