Python 3和Tkinter的类聚合(类中的类)

时间:2014-12-22 19:59:08

标签: python oop tkinter

它表示没有定义base_obj。但我确实已经定义了它。那我为什么会收到这个错误?

这是代码:

from tkinter import *

root = Tk()

class BaseClass:
    def __init__(self,an_int,a_string):
       self.the_int = an_int
       self.the_string = a_string

class BiggerClass:
    def __init__(self,an_instance_of_BaseClass,big_class_string,big_class_int,new_name):
        self.the_instance_of_BaseClass = an_instance_of_BaseClass   #here we are aggregating the base class into the bigger class
        self.the_big_class_string = big_class_string
        self.the_big_class_int = big_class_int
        self.the_big_class_new_name = new_name

base_int_var = IntVar()
base_string_var = StringVar()

bigger_name_var = StringVar()

entry_base_int = Entry(root,textvariable = base_int_var).pack()
entry_base_string = Entry(root,textvariable = base_string_var).pack()

big_new_name_var = StringVar()
entry_bigger_name = Entry(root, textvariable = bigger_name_var).pack()
entry_big_new_name = Entry(root,textvariable = big_new_name_var).pack()

def create_base_class_instance():
    global base_obj
    base_obj = BaseClass(base_int_var.get(),base_string_var.get())  # I define 'base_obj' here

list_of_bigs = []

def create_bigger_class_instance(big_handle):
    bigger_name_var = big_handle
    big_handle = BiggerClass(base_obj,bigger_name_var.get(),55,big_new_name_var.get())
    list_of_bigs.append(big_handle)
    #global big_obj
    #big_obj = BiggerClass(base_obj,bigger_name_var.get(),45)

create_base_class_button = Button(root, text ="create base class", command = create_base_class_instance).pack()
create_big_class_button = Button(root, text ="create big class", command = create_bigger_class_instance(big_new_name_var)).pack()

match_name_var = StringVar()
entry_match_name = Entry(root,textvariable = match_name_var).pack()

def my_button_method():
    for a_big in list_of_bigs:
        if a_big.the_big_class_new_name == match_name_var:
            print(a_big.the_instance_of_BaseClass.the_string)

   #print(big_obj.the_instance_of_BaseClass.the_int)

#bigger_class_obj = BiggerClass(base_obj,"hello this is the big class",45)
button_print_out = Button(root,text = "press me", command = my_button_method).pack()


root.mainloop()

这是错误消息:

Traceback (most recent call last):
  File "C:/Users/TOTTY/PycharmProjects/my game/aggregation practice fork 1.py", line 45, in <module>
    create_big_class_button = Button(root, text ="create big class", command = create_bigger_class_instance(big_new_name_var)).pack()
  File "C:/Users/TOTTY/PycharmProjects/my game/aggregation practice fork 1.py", line 39, in create_bigger_class_instance
    big_handle = BiggerClass(base_obj,bigger_name_var.get(),55,big_new_name_var.get())
NameError: name 'base_obj' is not defined

3 个答案:

答案 0 :(得分:0)

您已在create_base_class_instance函数中定义了该对象,并且您在my_button_method中调用它。

您应该在外面初始化它,并在两个函数中使用global关键字。

然而,使用全局变量被视为代码气味。我建议找另一个解决方案,例如将base_obj作为参数传递给两个函数。

base_obj = None

def some_function():
    global base_obj
    # some code referencing base_obj

def other_function():
    global base_obj
    # some code referencing base_obj

答案 1 :(得分:0)

看看这行代码:

create_big_class_button = Button(..., command = create_bigger_class_instance(big_new_name_var)).pack()

您正在立即调用create_bigger_class_instance(...),并将其结果分配给该命令。由于create_bigger_class_instance依赖于base_obj的存在,并且您还没有创建base_obj,因为它与按钮点击相关联,您会收到错误。

(另请注意,执行create_big_class_button = Button(...).pack()之类的操作始终会将create_big_class_button设置为None,因为这是pack()返回的内容。)

答案 2 :(得分:0)

Python中的函数仅在调用时执行。关键字global用于表示此处使用的变量与全局范围中的变量相同。因此,您需要在主类中添加声明语句,而不是在任何子函数中添加。

例如你必须写

base_obj = None

在调用两个函数之一之前的主类中。您在第二个函数中不需要global base_obj,因为您没有为其分配任何值。