1

I'm simply trying to reference an inherited Tkinter screen in a subclass, but for some reason I receive this error:

AttributeError: 'SignUpScreen' object has no attribute '_SignUpScreen__window'

After I try to execute:

self.__signupScreen = SignUpScreen()

And the class code is:

from tkinter import *

class Screen:

    def __init__(self, screenTitle, size):
        self.__window = Tk()
        self.__window.title(screenTitle)
        self.__SIZE = size #W x H

    def close(self):
        #Save all data, then
        self.__window.destroy()

class SignUpScreen(Screen):

    def __init__(self):
        super().__init__("Sign Up", "700x400")

        self.__titlelbl = Label(self.__window, text="Sign Up Window", font=("Arial Bold", 22))

    def run(self):
        self.__titlelbl.grid(column=0, row=0)
        self.__window.mainloop()

The IDE claims the error occurs at the following line:

self.__titlelbl = Label(self.__window, text="Sign Up Window", font=("Arial Bold", 22))

I do not understand what the issue is. Can anyone spot the issue?

2
  • Because you are using double-underscores. That's their whole point is to prevent a subclass from accessing the parent class attribute. Commented Mar 19, 2020 at 9:27
  • Oh ok, I had no idea. I was taught to use "_" in front of class variables, but I somehow translated that to "__". Thank you for straightening this out! Commented Mar 29, 2020 at 3:23

1 Answer 1

2

That's because of Python's name mangling:

Since there is a valid use-case for class-private members (namely to avoid name clashes of names with names defined by subclasses), there is limited support for such a mechanism, called name mangling. Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.

You have two options:

  1. Either change self.__window to a name without double underscore at the beginning

  2. Use it as self._Screen__window (not recommended).

Sign up to request clarification or add additional context in comments.

2 Comments

The convention for implementation variables / functions / methods / attributes (the equivalent of Java / C++ 'protected') is one single leading underscore. The double-leading underscore things is actually almost never used by anyone.
You should never use self._Screen__window

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.