Can Python3 class instances be forced to be global

2019-06-14 19:40发布

问题:

Even though global Python objects tend to be bad, I more or less forced to use them with module curses. I currently have this:

class Window:
    def __init__(self, title, h, w, y, x):
        self.window = curses.newwin(h, w, y, x)
        self.window.box()
        self.window.hline(2, 1, curses.ACS_HLINE, w-2)
        self.window.addstr(1, 2, title)
        self.window.refresh()

global top_win
top_win = Window('Top window', 6, 32, 3, 6)

I am wondering whether it would be possible to get rid of the global line by adding something to the class definition or initialisation?

class Window:
    def __init__(self, title, h, w, y, x):
        # Some global self magic
        self.window = curses.newwin(h, w, y, x)
        self.window.box()
        self.window.hline(2, 1, curses.ACS_HLINE, w-2)
        self.window.addstr(1, 2, title)
        self.window.refresh()

top_win = Window('Top window', 6, 32, 3, 6)

回答1:

Global class pattern

Despite the reflexive downvotes whenever the word global is seen, I resolved my issue anyhow by applying the equally controversial global class pattern.

class win:
    pass

class Window:
    def __init__(self, title, h, w, y, x):
        self.window = curses.newwin(h, w, y, x)
        self.window.box()
        self.window.hline(2, 1, curses.ACS_HLINE, w-2)
        self.window.addstr(1, 2, title)
        self.window.refresh()

win.top = Window('Top window', 6, 32, 3, 6)

This results in win.top being accessible anywhere in my Python script, just like any global variable would have been, but then nice and neat in a more controlled manner.

This is quite handy for defining new curses windows inside the main() routine which is typically wrapped inside a curses.wrapper(main). Follow this link for a full blown Python3 curses example.