Проблема с дизайном ООП — объект ‘postulantet’ не имеет атрибута ‘tabla_postulante’

#python #python-3.x #oop #tkinter

#python #python-3.x #ооп #tkinter

Вопрос:

У меня проблема с использованием tkinter и объектно-ориентированного программирования. У меня есть 3 функции:

  1. Сначала у меня есть v2() функция, которая позволяет открывать второе окно с помощью кнопки и отображать данные, сохраненные в базе данных

  2. Моя вторая функция agregar_postulantes() . Эта функция сохраняет данные в базе данных.

  3. Моя третья функция — это та, которая сохраняет данные agregar_postulantes() и отправляет их в v2() функцию.

Я хочу подчеркнуть, что все функции находятся в одном классе и объявлены вне __init__() .

Краткая версия кода:

 def v2(self):
    self.tabla_postulante=ttk.Treeview(tablaBD,columns=("Name","last name","id")
    self.tabla_postulante.heading("Name",text="Name")
    self.tabla_postulante.heading("last name",text="last name")
    self.tabla_postulante.heading("id",text="id")

    self.tabla_postulante['show']='headings'
    self.tabla_postulante.column("Name",width=100)
    self.tabla_postulante.column("last name",width=100)
    self.tabla_postulante.column("id",width=100)
    self.fetch_all()
    self.tabla_postulante.pack(fill=BOTH,expand=1)

def agregar_postulantes(self):
    con = pymysql.connect(host="localhost", user="root",password="", database="postulantebd")
    cur = con.cursor()
    cur.execute("insert into postulantes values(%s, %s, %s)",(
            self.name_var.get(),
            self.lastname_var.get(),
            self.id_var.get(),
            ))
    con.commit()
    self.fetch_all()
    con.close()

def fetch_all(self):
    con = pymysql.connect(host="localhost", user="root",password="", database="postulantebd")
    cur = con.cursor()
    cur.execute("select * from postulantes")
    rows=cur.fetchall()
    if len(rows)!=0:
        self.tabla_postulante.delete(*self.tabla_postulante.get_children())
        for row in rows:
            self.tabla_postulante.insert('',END,values=row)
        con.commit()
    con.close()
  

Появляется следующая ошибка:

 Traceback (most recent call last):
  File "C:UsersdimitriAppDataLocalProgramsPythonPython36-32libtkinter__init__.py", line 1705, in __call__
    return self.func(*args)
  File "C:UsersdimitriDocumentsProgramas de Yolopracticadeinterfazypootkinterinterfaz_tesis_poo.py", line 273, in agregar_postulantes
    self.fetch_all()
  File "C:UsersdimitriDocumentsProgramas de Yolopracticadeinterfazypootkinterinterfaz_tesis_poo.py", line 282, in fetch_all
    self.tabla_postulante.delete(*self.tabla_postulante.get_children())
AttributeError: 'postulante' object has no attribute 'tabla_postulante'
  

ошибка связана с тем, что я вызываю функцию v2 после сохранения данных с использованием двух других функций
Как я могу v2 впоследствии вызвать функцию и не показывать ошибки?

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

1. Вам необходимо вызвать v2 , который создает tabla_postulante перед другими методами, которые его используют. Из этого примера неясно, был ли выполнен этот вызов.

2. Неясно ли сообщение об ошибке? Например, вы понимаете, что такое an attribute ?

3. Я думаю, что tabla_postulante является атрибутом, объявленным в версии 2.

Ответ №1:

Кажется вероятным, что, как AttributeError указано, self не имеет tabla_postulante атрибута. Поскольку вы создаете table_postulante атрибут self в v2 функции, я бы предположил, что вы не определяете self.table_postulante в __init__() or, который вы не вызываете v2() перед вызовом fetch_all() .

Что должно означать, что у вас есть пара вариантов:

  1. создайте некоторую логику, fetch_all() которая проверяет наличие self.tabla_postulante и выполняется только в том случае, если этот атрибут найден. Это может принимать форму try except оператора / .

  2. В качестве альтернативы, определите self.tabla_postulante атрибут в вашем вызове __init__() при создании экземпляра объекта.

Обновить

Немного подробнее о реализации того, что я описал выше. Я предполагаю, что вы не создаете self.tabla_postulante атрибут для своего класса в __init__() , поскольку, если бы вы были, вы бы не получали a ValueError , когда функция ищет его.

Итак, это дает вам пару вариантов. Можно было бы просто убедиться, что при создании экземпляра вашего класса __init__() создается такой self.table_postulante атрибут:

 class ClassName:
    def __init__(self):
        #create attribute here
        self.table_postulante = ttk.Treeview(tablaBD,columns=("Name", "last name","id")
        ...
  

Другой вариант, если это не имеет смысла для разрабатываемого вами приложения, — выполнить некоторую обработку исключений внутри fetch_all() . Например, вы могли бы сделать что-то вроде:

 if len(rows)!=0:
    try:
        self.tabla_postulante.delete(*self.tabla_postulante.get_children())
        for row in rows:
            self.tabla_postulante.insert('',END,values=row)
        con.commit()
    except:
        #define some appropriate response to this attribute not existing here
  

Ваш вариант использования, конечно, определит, какой подход имеет наибольший смысл. Надеюсь, это поможет.

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

1. вы правы, я вызываю 2-ю и 3-ю функции перед использованием первой. не могли бы вы быть немного более конкретными для проверки? Я новичок

2. Абсолютно! Я добавлю это в ответ, чтобы я мог воспользоваться Markdown, чтобы сделать его красивым.