Является ли эта ошибка ‘self isn’t defined’ проблемой области видимости?

#python #oop

#python #ооп

Вопрос:

В моем основном скрипте у меня есть следующий код:

 class Sequence:

    def __init__(self, colour, text):
        self.colour = colour
        self.width = 5
        self.height = 5
        self.text = text

    def create_window(self, root):
        self.name=tk.Label(root,text=self.text, wdith=self.width, height=self.height, 
        bg=self.colour
        self.name.pack()
 

В моем скрипте с графическим интерфейсом этот код выполняется как

 Sequence.create_window(self, root)
 

Я получаю ошибку:

 Sequence.create_window(self, root) NameError: name 'self' is not defined
 

Я не совсем уверен, как это исправить, связано ли это с областью действия программы?

Комментарии:

1. Пожалуйста, просмотрите docs.python.org/3/tutorial/classes.html#class-objects

2. Сначала вам нужно создать экземпляр Sequence класса. Затем вы можете вызвать create_window метод экземпляра, не передавая self его в качестве аргумента.

3. Я имею в виду, да, это принципиально, потому что вы пытаетесь использовать переменную, которая не определена в этой области. Если бы у вас была функция, def plus_two(x): return x 2 что бы вы ожидали plus_two(x) от работы? Нет, это выдало бы ошибку NameError, потому x что в вызывающем нет. Но также вам принципиально необходимо понимать ООП, это методы в классе, предполагается, что сначала создается экземпляр класса

Ответ №1:

Сначала вам нужно инициализировать объект:

 class Sequence:

    def __init__(self, colour, text):
        self.colour = colour
        self.width = 5
        self.height = 5
        self.text = text

    def create_window(self, root):
        self.name=tk.Label(root,text=self.text, wdith=self.width, height=self.height, 
        bg=self.colour)
        self.name.pack()

sequence = Sequence("blue", "test")
sequence.create_window(root)
 

Комментарии:

1. Когда я делаю это, я получаю другую ошибку, в которой говорится, что ‘root’ не определен.

2. Да, очевидно. Потому что сначала вам нужно определить root 🙂 Но я не знаю, что такое root. Пожалуйста, ознакомьтесь с документацией 🙂

Ответ №2:

root — это переменная, определенная в методе create_window

tk.Label необходимо поместить в окно или фрейм, который передается в качестве первого аргумента.

 import sys
if sys.version_info.major == 2
  # for python 2
  import Tkinter as tk
else
  # for python 3
  import tkinter as tk

class Sequence:

    def __init__(self, colour, text):
        self.colour = colour
        self.width = 5
        self.height = 5
        self.text = text

    def create_window(self, root):
        self.name=tk.Label(root, text=self.text, wdith=self.width, height=self.height, 
        bg=self.colour)
        self.name.pack()

if __name__ == "__main__":
    root = tk.Tk()

    sequence = Sequence("blue", "test")
    sequence.create_window(root)

    root.mainloop()