【问题标题】:global variable in main not getting recognised in another function in pythonmain 中的全局变量在 python 的另一个函数中没有被识别
【发布时间】:2013-07-27 22:29:04
【问题描述】:

下面的代码创建一个布局并在布局中显示一些文本。接下来,使用 urwid 库中的原始显示模块将布局显示在控制台屏幕上。但是运行代码失败,因为在 main 中声明的全局变量 ui 在另一个函数中无法识别。

运行时出错代码为:
Traceback (most recent call last):
File "./yamlUrwidUIPhase6.py", line 97, in <module>
main() File "./yamlUrwidUIPhase6.py", line 90, in main
form = FormDisplay() File "./yamlUrwidUIPhase6.py", line 23, in __init__
palette = ui.register_palette([
NameError: global name 'ui' is not defined

代码:

import sys  
sys.path.append('./lib')  
import os  
from pprint import pprint  
import random  
import urwid  
global ui

class FormDisplay(object):

    def __init__(self):
        self.ui = urwid.raw_display.Screen()
        palette = ui.register_palette([
            ('Field', 'dark green, bold', 'black'), # information fields, Search: etc.
            ('Info', 'dark green', 'black'), # information in fields
            ('Bg', 'black', 'black'), # screen background
            ('InfoFooterText', 'white', 'dark blue'), # footer text
            ('InfoFooterHotkey', 'dark cyan, bold', 'dark blue'), # hotkeys in footer text
            ('InfoFooter', 'black', 'dark blue'),  # footer background
            ('InfoHeaderText', 'white, bold', 'dark blue'), # header text
            ('InfoHeader', 'black', 'dark blue'), # header background
            ('BigText', RandomColor(), 'black'), # main menu banner text
            ('GeneralInfo', 'brown', 'black'), # main menu text
            ('LastModifiedField', 'dark cyan, bold', 'black'), # Last modified:
            ('LastModifiedDate', 'dark cyan', 'black'), # info in Last modified:
            ('PopupMessageText', 'black', 'dark cyan'), # popup message text
            ('PopupMessageBg', 'black', 'dark cyan'), # popup message background
            ('SearchBoxHeaderText', 'light gray, bold', 'dark cyan'), # field names in the search box
            ('SearchBoxHeaderBg', 'black', 'dark cyan'), # field name background in the search box
            ('OnFocusBg', 'white', 'dark magenta') # background when a widget is focused
           ])
        urwid.set_encoding('utf8')

    def main(self):
        #self.view = ui.run_wrapper(formLayout)
        self.view = formLayout()
        self.ui.start()
        self.loop = urwid.MainLoop(self.view, self.palette, unhandled_input=self.unhandled_input)
        self.loop.run()

    def unhandled_input(self, key):
        if key == 'f8':
          quit()
          return


def formLayout():
    text1 = urwid.Text("Urwid 3DS Application program - F8 exits.")
    text2 = urwid.Text("One mission accomplished")

    textH = urwid.Text("topmost Pile text")
    cols = urwid.Columns([text1,text2])
    pile = urwid.Pile([textH,cols])
    fill = urwid.Filler(pile)

    textT  = urwid.Text("Display") 

    textSH = urwid.Text("Pile text in Frame")
    textF = urwid.Text("Good progress !")

    frame = urwid.Frame(fill,header=urwid.Pile([textT,textSH]),footer=textF)
    dim = ui.get_cols_rows()

    ui.draw_screen(dim, frame.render(dim, True))
    return

def RandomColor():
    '''Pick a random color for the main menu text'''
    listOfColors = ['dark red', 'dark green', 'brown', 'dark blue',
                    'dark magenta', 'dark cyan', 'light gray',
                    'dark gray', 'light red', 'light green', 'yellow',
                    'light blue', 'light magenta', 'light cyan', 'default']
    color = listOfColors[random.randint(0, 14)]
    return color

def main():
    form = FormDisplay()
    form.main()

########################################
##### MAIN ENTRY POINT
########################################
if __name__ == '__main__':
    main()

我不想更改函数 formLayout,因为我打算在这个基本代码框架中添加更多内容,其中将添加另一个函数,该函数重复调用 formLayout 以根据从 yml 文件中读取的值不断更新屏幕。

【问题讨论】:

  • 请注意我在原线程 stackoverflow.com/questions/17898314/… 中所做的更改,此外,您能否发布引发堆栈跟踪的代码。
  • 您还需要在任何函数或类之外声明 ui 才能使 global ui 声明生效。
  • @Jonathan 我将全局 ui 放在导入之后,但仍然无法正常工作。我应该用我当前的代码和错误消息开始一个新问题吗?因为我不知道如何将正确缩进的代码放在此处的评论框中。
  • @Ketouem 我把代码移到这里了,我们在这里讨论一下。将您的更改合并到代码中。打印的错误消息的新跟踪。还是不行
  • @Jonathan 更新了代码(上图)以使全局 ui 在导入后立即出现。还是不行。给出了最新的堆栈跟踪。

标签: python user-interface python-2.7 console-application urwid


【解决方案1】:

好的,感谢人们提出的各种建议,帮助我了解了全球范围界定。我在这里按照 Jeff Shannon 的回答:Using global variables in a function other than the one that created them 似乎能够摆脱使用全局 ui 引起的名称范围错误。这是我所做的,我在导入后立即使用了 ui=urwid.raw_display.Screen(),然后在使用它的函数中声明了全局 ui。但现在我得到了另一种错误。认为最好从现在获得的错误开始一个新问题。

【讨论】:

    【解决方案2】:

    main 中写入global ui 除了使main 本身可以写入一个名为ui 的全局变量之外,什么都不做。如果您想从其他函数(例如您的__init__)写入该全局变量,您还需要在其中包含global 声明。您要分配给全局变量的每个函数都必须有自己的 global 声明。

    【讨论】:

    • 我使用全局 ui 的主要目的是因为我想要控制台屏幕的句柄(这里由 urwid 提供的原始显示模块表示)。这样我就可以编写几个函数来创建顶级框小部件,然后将更多的子小部件添加到框小部件,从而我可以在屏幕上写入/修改。如果我对每个函数都有一个全局 ui 声明,那么函数调用会反映全局控制台屏幕中的变化吗?
    • @tauseef_india:是的,如果您在每个使用ui 的函数中使用global ui,那么至少所有这些函数都可以写入该变量。我不知道uiwid 是如何工作的,所以我不能说这是否意味着它真的可以工作并做你想做的事情,但至少你不会遇到这些name not defined 问题。
    • 在每个使用 ui 的函数中声明了全局 ui,仍然不起作用:-(
    • 它显示了与上面的堆栈跟踪中给出的类似的错误消息。我试图将乔纳森的建议纳入上面的另一个答案,但这也不起作用。
    • 现在代码更改时出现属性错误。 [stackoverflow.com/questions/17908588/… 的新问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-02
    • 1970-01-01
    • 2019-08-03
    相关资源
    最近更新 更多