2014-02-06 5 views
0

Я искал эту ошибку за весь день, пытаясь ее решить, и решил, что мне нужна помощь, я предполагаю, что она говорит мне, что «countrynames» либо не определен, не заполнен, либо имеет любые значения, но он используется ранее в классе «mysqlbusiness» ok, я пытаюсь отобразить простую строку текста, которая показывает, какой элемент был выбран из выпадающего списка, список заполняется кортежем, а команда для подачи заявки выбирается радиокнопкой, сообщение является вежливым примечанием!python 'function' не имеет атрибута

TkInter ошибка заключается в следующем:

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__ 
    return self.func(*args) 
    File "S:\python\jon\wrt_toolkit_v5\toolbox_v7.py", line 141, in sendGift 
    name = mysqlbusiness.mysqlConnect.countrynames[idx] 
AttributeError: 'function' object has no attribute 'countrynames' 

Фрагмент кода это,

class mysqlbusiness: 

    def mysqlConnect(): 
     import pymysql 
     sqlUsr = MysqlUsr.get() 
     sqlpwd = Mysqlpwd.get() 
     conn = pymysql.connect(host='192.168.0.27', user= sqlUsr, passwd=sqlpwd, db='information_schema') 
     cursor = conn.cursor() 
     cursor.execute("SELECT SCHEMA_NAME FROM SCHEMATA") 
     schema_names = cursor.fetchall() 
     schema_tuple = tuple(schema_names) 
     countrynames = (schema_tuple) 
     cnames = (countrynames) 
     lbox.insert(END, *schema_names) 
     # Colorize alternating lines of the listbox 
     for i in range(0,len(cnames),2): 
      lbox.itemconfigure(i, background='#CEECF5') 
     # create a vertical scrollbar to the right of the listbox 
     yscroll = tk.Scrollbar(command=lbox.yview, orient=tk.VERTICAL) 
     yscroll.grid(row=15, column=6, sticky='ns') 
     lbox.configure(yscrollcommand=yscroll.set) 
     lbox.selection_set(0) 
     conn.close() 

    # Called when the user double clicks an item in the listbox, presses 
    # the "apply" button, or presses the Return key. In case the selected 
    # item is scrolled out of view, make sure it is visible. 
    # 
    # Figure out which schema is selected, which command (connect or delete) is selected with the radiobuttons, and provide feedback. 
    def listConnection(*args): 
     idxs = lbox.curselection() 
     if len(idxs)==1: 
      idx = int(idxs[0]) 
     lbox.see(idx) 
     name = mysqlbusiness.mysqlConnect.countrynames[idx] 
     # Gift sending left as an exercise to the reader 
     sentmsg.set("%s %s" % (gifts[gift.get()], name)) 
     lbox.bind('<Double-1>', listConnection) 
     mainframe.bind('<Return>', listConnection) 

ответ

0

Вы делаете несколько ошибок:

  • Вы используете класс, но определен только функции. Не используйте классы для создания пространств имен, Python - это не Java, а не требует классов, которые будут использоваться.

  • Ваш mysqlConnect() функция ничего не возвращает. Вы не можете ссылаться на локальные имена в функциях.

  • Вы фактически не назовете функцию mysqlConnect().

  • Вы смешиваете извлечение данных с обновлением пользовательского интерфейса; лучше разделить это на отдельные функции.

  • Вы не извлекаете столбец из строк; каждая строка получается из базы данных - это кортеж со столбцами (один в этом случае).

  • Вы используете несколько имен переменных для одного и того же набора результатов; нет необходимости действительно делать результаты кортежем, например.

  • Не требуется переустанавливать обработчики событий каждый раз, когда вызывается listConnection.

Исправленный код:

import pymysql 

def countrynames(): 
    sqlUsr = MysqlUsr.get() 
    sqlpwd = Mysqlpwd.get() 
    conn = pymysql.connect(host='192.168.0.27', user=sqlUsr, 
          passwd=sqlpwd, db='information_schema') 
    cursor = conn.cursor() 
    cursor.execute("SELECT SCHEMA_NAME FROM SCHEMATA") 
    countrynames = [row[0] for row in cursor] 
    conn.close() 
    return countrynames 

def set_countrynames_lbox(countrynames) 
    lbox.insert(END, *countrynames) 

    # Colorize alternating lines of the listbox 
    for i in range(0, len(countrynames), 2): 
     lbox.itemconfigure(i, background='#CEECF5') 

    # create a vertical scrollbar to the right of the listbox 
    yscroll = tk.Scrollbar(command=lbox.yview, orient=tk.VERTICAL) 
    yscroll.grid(row=15, column=6, sticky='ns') 
    lbox.configure(yscrollcommand=yscroll.set) 
    lbox.selection_set(0) 


# Called when the user double clicks an item in the listbox, presses 
# the "apply" button, or presses the Return key. In case the selected 
# item is scrolled out of view, make sure it is visible. 
# 
# Figure out which schema is selected, which command (connect or delete) is selected with the radiobuttons, and provide feedback. 
def listConnection(*args): 
    idxs = lbox.curselection() 
    if len(idxs)==1: 
     idx = int(idxs[0]) 
    lbox.see(idx) 

    cnames = countrynames() 
    # optional, set the lbox again with 
    # set_countrynames_lbox(cnames) 

    name = cnames[idx] 

    # Gift sending left as an exercise to the reader 
    sentmsg.set("%s %s" % (gifts[gift.get()], name)) 

# moved out of the functions 
lbox.bind('<Double-1>', listConnection) 
mainframe.bind('<Return>', listConnection) 
+0

Wowsers! я чувствовал себя глубже и борюсь за этот проект, и это показывает, насколько! Я думал, что мне нужно создать класс, потому что я хотел, чтобы «countrynames» можно было использовать в другом месте вне функции, я думал, что мне нужно определить кортеж, а затем взять имя, которое я использовал для определения и вызова. Измененный код, который вы опубликовали, не позволяет перечислить кортеж в списке, хотя и, перемещая команду привязки вне определения, выдает неопределенную ошибку lbox, но я глубоко подозреваю, что это связано с тем, что остальная часть моего кода неверна в зависимости от того, что вы показали меня здесь. спасибо :) – jon141

+0

Да, для создания рабочего кода недостаточно контекста, мне пришлось придерживаться контекста, который у меня был здесь; но 'lbox' также является глобальным в вашем исходном коде (а также' mainframe'). –

+0

Я также не знаю, какой тип объекта 'lbox' * есть *, поэтому я не знаю, какие значения он ожидает в качестве аргументов; это может быть так, что он ожидает только один аргумент, например, в этом случае вам нужно отбросить '*', или если он ожидает несколько аргументов, но каждая из них представляет собой последовательность (строки, скажем), тогда вам понадобится генератор чтобы получить данные из простого плоского списка названий стран. –

Смежные вопросы