2012-06-23 4 views
0

Я пытаюсь использовать глобальную переменную. Я объявлял его глобальным для начала и объявлял его при каждом упоминании, но после завершения первой функции я получаю NameError. Вот код, и я думаю, что я с ума сходил, но я не могу найти проблему.Ошибка глобальной переменной, несмотря на объявление переменной как глобальной в каждой функции

def on_servername_insertatcursor(self, widget): 
    global output 
    output = StringIO.StringIO()   
    servername = widget.get_text() 
    output.write("USHARE_NAME="+servername+'\n') 

def on_netif_changed(self, widget): 
    netif = widget.get_active_text() 
    global output 
    output.write("USHARE_IFACE="+netif+'\n') 

def on_port_insertatcursor(self, widget): 
    global output 
    port = widget.get_text() 
    output.write("USHARE_PORT="+port+'\n') 

def on_telprt_insertatcursor(self, widget): 
    global output 
    telprt = widget.get_text() 
    output.write("USHARE_TELNET_PORT="+telprt+'\n') 

def on_dirs_insertatcursor(self, widget): 
    global output 
    dirs = widget.get_text() 
    output.write("USHARE_DIR="+dirs+'\n') 

def on_iconv_toggled(self, widget): 
    global output 
    iconv = widget.get_active() 
    if iconv == True: 
     output.write("USHARE_OVERRIDE_ICONV_ERR="+"True"+'\n') 
    else: 
     output.write("USHARE_OVERRIDE_ICONV_ERR="+"False"+'\n') 

def on_webif_toggled(self, widget): 
    global output 
    webif = widget.get_active() 
    if webif == True: 
     output.write("USHARE_ENABLE_WEB="+"yes"+'\n') 
    else: 
     output.write("USHARE_ENABLE_WEB="+"no"+'\n') 

def on_telif_toggled(self, widget): 
    global output 
    telif = widget.get_active() 
    if telif == True: 
     output.write("USHARE_ENABLE_TELNET="+"yes"+'\n') 
    else: 
     output.write("USHARE_ENABLE_TELNET="+"no"+'\n') 

def on_xbox_toggled(self, widget): 
    global output 
    xbox = widget.get_active() 
    if xbox == True: 
     output.write("USHARE_ENABLE_XBOX="+"yes"+'\n') 
    else: 
     output.write("USHARE_ENABLE_XBOX="+"no"+'\n') 

def on_dlna_toggled(self, widget): 
    global output 
    dlna = widget.get_active() 
    if dlna == True: 
     output.write("USHARE_ENABLE_DLNA="+"yes"+'\n') 
    else: 
     output.write("USHARE_ENABLE_DLNA="+"no"+'\n') 

def on_commit_clicked(self, widget): 
    commit = output.getvalue() 
    logfile = open('/home/boywithaxe/Desktop/ushare.conf','w') 
    logfile.write(commit) 

def on_endprogram_clicked(self, widget): 
    sys.exit(0) 

Что удивительно, что, когда insertatcursor (исходя из Gtk.TextBuffer.insert_at_cursor()) будет заменить активации, код работает отлично, за исключением того, я не хочу, чтобы пользователю нужно нажать клавишу ВВОД после каждой ввод данных.

EDIT. Traceback выглядит следующим образом

Traceback (most recent call last): 
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line  58, in on_netif_changed 
output.write("USHARE_IFACE="+netif+'\n') 
NameError: global name 'output' is not defined 

Сделав изменения, предложенные @jdi (Спасибо Кстати, я вижу логику этого), то Traceback я получаю следующим образом:

Traceback (most recent call last): 
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 55, in on_netif_changed 
OUTPUT.write("USHARE_IFACE="+netif+'\n') 
NameError: global name 'OUTPUT' is not defined 
Traceback (most recent call last): 
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 72, in on_iconv_toggled 
OUTPUT.write("USHARE_OVERRIDE_ICONV_ERR="+"True"+'\n') 
NameError: global name 'OUTPUT' is not defined 
Traceback (most recent call last): 
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 79, in on_webif_toggled 
OUTPUT.write("USHARE_ENABLE_WEB="+"yes"+'\n') 
NameError: global name 'OUTPUT' is not defined 
Traceback (most recent call last): 
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 86, in on_telif_toggled 
OUTPUT.write("USHARE_ENABLE_TELNET="+"yes"+'\n') 
NameError: global name 'OUTPUT' is not defined 
Traceback (most recent call last): 
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 93, in on_xbox_toggled 
OUTPUT.write("USHARE_ENABLE_XBOX="+"yes"+'\n') 
NameError: global name 'OUTPUT' is not defined 
Traceback (most recent call last): 
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 100, in on_dlna_toggled 
OUTPUT.write("USHARE_ENABLE_DLNA="+"yes"+'\n') 
NameError: global name 'OUTPUT' is not defined 
Traceback (most recent call last): 
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 105, in on_commit_clicked 
commit = OUTPUT.getvalue() 
NameError: global name 'OUTPUT' is not defined 
+2

Почему вы вложили столько «глобальных»? Также, пожалуйста, напишите * фактический след ошибки *, поскольку это будет содержать причину. Я подозреваю, что 'on_servername_insertatcursor' не был вызван первым .. –

+3

, если вы никогда не * присваиваете * output (т.е.' output = 3'), вы * не * должны сделать его глобальным. –

+1

Я не думаю, что вы пошли «сумасшедшим». Я думаю, что вы пошли «глобально сумасшедшим» – jdi

ответ

1

Ваш пример кода не требует глобального. Просто удалите его. Единственный раз, когда вам нужно использовать ключевое слово global в функции, вы должны назначить ему.

OUTPUT = StringIO.StringIO()   

def on_servername_insertatcursor(self, widget): 
    servername = widget.get_text() 
    OUTPUT.write("USHARE_NAME="+servername+'\n') 

def on_netif_changed(self, widget): 
    netif = widget.get_active_text() 
    OUTPUT.write("USHARE_IFACE="+netif+'\n') 

def on_port_insertatcursor(self, widget): 
    port = widget.get_text() 
    OUTPUT.write("USHARE_PORT="+port+'\n') 

def on_telprt_insertatcursor(self, widget): 
    telprt = widget.get_text() 
    OUTPUT.write("USHARE_TELNET_PORT="+telprt+'\n') 

def on_dirs_insertatcursor(self, widget): 
    dirs = widget.get_text() 
    OUTPUT.write("USHARE_DIR="+dirs+'\n') 

def on_iconv_toggled(self, widget): 
    iconv = widget.get_active() 
    if iconv == True: 
     OUTPUT.write("USHARE_OVERRIDE_ICONV_ERR="+"True"+'\n') 
    else: 
     OUTPUT.write("USHARE_OVERRIDE_ICONV_ERR="+"False"+'\n') 

Даже если вы хотите, чтобы иметь возможность восстановить свой объект StringIO в функции, то все равно не требуется назначение или глобальное ключевое слово:

def reset_output(self): 
    OUTPUT.seek(0) 
    OUTPUT.truncate() 

Доказательство того, что он работает

import StringIO 

OUTPUT = StringIO.StringIO()   

def foo(): 
    OUTPUT.write('foo') 

def bar(): 
    OUTPUT.write('bar') 

def print_output(): 
    print OUTPUT.getvalue() 

def reset_output(): 
    OUTPUT.seek(0) 
    OUTPUT.truncate() 

if __name__ == "__main__": 
    foo() 
    bar() 
    print_output() 
    reset_output() 
    print_output() 

Выход

$ python test.py 
foobar 

$ 
+0

У меня было это для начала, и это дало мне то же самое Traceback. Это то, что привело меня к проверке 'global's в первую очередь. – boywithaxe

+0

@boywithaxe: просто добавили тест для вас. – jdi

+0

Ваш пример отлично работает, но когда применяется к моему коду, это не так. Я начинаю думать, что это виджеты и их соответствующие сигналы, иначе почему изменение с 'insertatcursor' на' activ' на виджетах TextBox' влияет на конечный результат. – boywithaxe

0

Попробуйте переставить output = StringIO.StringIO() снаружи и прежде всего функции в файле.

0

Ну, проблема с вопросом прискорбны отступы :) Глядя на PyGTK docs показывает, что on_... функции, показанная действительно методы класса, а не глобальные функций, так что «глобальные» переменный, вероятно, на самом деле не глобальные, но и член класса (просто посмотрите на параметр self в определениях методов).

Я дал более подробный ответ на askubuntu, вот фрагмент кода, который показывает, что должно быть сделано:

class MyApp(gtk.Window): 

    output = None 

    def __init__(...): 
     ... 
     self.output = StringIO.StringIO() 

    def on_servername_insertatcursor(self, widget):  
     servername = widget.get_text() 
     self.output.write("USHARE_NAME="+servername+'\n') 

    def on_netif_changed(self, widget): 
     netif = widget.get_active_text() 
     self.output.write("USHARE_IFACE="+netif+'\n') 

Там нет абсолютно никакого PyGTK конкретного или сигналы конкретного волшебства :)

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