【问题标题】:class aggregation (classes within classes) with Python 3 and Tkinter使用 Python 3 和 Tkinter 进行类聚合(类中的类)
【发布时间】:2014-12-22 19:59:07
【问题描述】:

它说 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

【问题讨论】:

    标签: python oop tkinter


    【解决方案1】:

    您已经在 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
    

    【讨论】:

      【解决方案2】:

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

      例如你必须写

      base_obj = None
      

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

      【讨论】:

        【解决方案3】:

        看这行代码:

        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() 返回的内容。)

        【讨论】:

          猜你喜欢
          • 2017-08-27
          • 1970-01-01
          • 1970-01-01
          • 2012-03-24
          • 1970-01-01
          • 2019-01-06
          • 2015-05-13
          • 1970-01-01
          • 2020-07-21
          相关资源
          最近更新 更多