Python类调用问题

时间:2016-06-04 04:29:26

标签: python python-3.x

我在从另一个类调用def语句时遇到问题。我想要做的是从一个类中获取变量然后将其发送到另一个类然后再将其发送回来但是我在执行它时遇到了麻烦。

以下是我的尝试:

from tkinter import *
from tkinter import ttk

class Logic:
   def __init__(self,measurements,measurements1,Text_Length_Left,Text_Length_Right):
       self.measurements = measurements
       self.measurements1 = measurements1
       self.Text_Length_Left = Text_Length_Left
       self.Text_Length_Right = Text_Length_Right

   as_meter = dict(mm=0.001, cm=0.01, inch=0.0254,ft=0.3048, yd=0.9144, m=1.0,km=1000.0, mi=1609.344,)
   def update_length(self, *args,measurements, measurements1, Text_Length_Left, Text_Length_Right):
       try:
           v = float(self.Text_Length_Left.get())
       except ValueError:
           self.Text_Length_Left.set('')
           self.Text_Length_Right.set('')
           return
       m = v * self.as_meter [self.measurements.get()]
       r = m/self.as_meter[self.measurements1.get()]
       self.Text_Length_Right.set("{:.3g}".format(r))

class GUI:
   def __init__(self,root):
       global a,b,c,d
       self.notebook = ttk.Notebook(root)
       self.notebook.pack()

       self.length_frame = ttk.Frame(self.notebook)
       self.weight_frame = ttk.Frame(self.notebook)
       self.temperature_frame = ttk.Frame(self.notebook)
       self.help_frame = ttk.Frame(self.notebook)

       self.notebook.add(self.length_frame, text = 'Length')

       #Combobox
       self.measurements = StringVar()
       self.Combobox_Length_Left = ttk.Combobox(self.length_frame, textvariable = self.measurements, values = ('mm', 'cm', 'inch', 'ft', 'yd', 'm', 'km', 'mi'), width = 10,state=['readonly'])
       self.Combobox_Length_Left.current(5)
       a = self.measurements
       self.measurements.trace('w', Logic.self.update_length())
       self.Combobox_Length_Left.grid(row = 2, column = 0, padx = 5, pady = 5, sticky = E)

       self.measurements1 = StringVar()
       self.Combobox_Length_Right = ttk.Combobox(self.length_frame, textvariable = self.measurements1, value = ('mm', 'cm', 'inch', 'ft', 'yd', 'm', 'km', 'mi'), width = 10,state = ['readonly'])
       self.Combobox_Length_Right.current(5)
       b = self.measurements1
       self.measurements1.trace('w', Logic.self.update_length())
       self.Combobox_Length_Right.grid(row = 2, column = 2, padx = 5, pady = 5, sticky = E)

       #Labels
       self.Conversion = ttk.Label(self.length_frame, text = 'Convertion:').grid(row = 1, column = 0, padx = 5, pady = 5, sticky = W)
       self.Label_Blank = ttk.Label(self.length_frame, text = '').grid(row = 1, column = 1, padx = 5, pady = 5, sticky = E)
       self.Label_To2 = ttk.Label(self.length_frame, text = 'to').grid(row = 2, column = 1, padx = 5, pady = 5, sticky = E)
       self.Label_To = ttk.Label(self.length_frame, text = 'to').grid(row = 3, column = 1, padx = 5, pady = 5, sticky = E)

       #Entry Boxes
       self.Text_Length_Left = StringVar()
       self.Entry_Length_Left = ttk.Entry(self.length_frame, textvariable = self.Text_Length_Left,width = 13)
       c = self.Text_Length_Left
       self.Text_Length_Left.trace('w', Logic.self.update_length())
       self.Entry_Length_Left.grid(row = 3, column = 0, padx = 5, pady = 5)

       self.Text_Length_Right = StringVar()
       d = self.Text_Length_Right
       self.Entry_Length_Right = ttk.Entry(self.length_frame, textvariable = self.Text_Length_Right,width = 13, state='readonly')
       self.Entry_Length_Right.grid(row = 3, column = 2, padx = 5, pady = 5)

       Logic(a,b,c,d)




root = Tk()
app = GUI(root)
root.title('Metric Calculator')
root.resizable(False,False)
root.mainloop()

这是我使用类继承的工作代码:

from tkinter import *
from tkinter import ttk

class Convertion:
    as_meter = dict(mm=0.001, cm=0.01, inch=0.0254,ft=0.3048, yd=0.9144, m=1.0,km=1000.0, mi=1609.344,)
    def update_length(self, *args):
        try:
            v = float(self.Text_Length_Left.get())
        except ValueError:
            self.Text_Length_Left.set('')
            self.Text_Length_Right.set('')
            return
        m = v * self.as_meter [self.measurements.get()]
        r = m/self.as_meter[self.measurements1.get()]
        self.Text_Length_Right.set("{:.5g}".format(r))

class GUI(Convertion):
    def __init__(self,root):
        self.notebook = ttk.Notebook(root)
        self.notebook.pack()

        self.length_frame = ttk.Frame(self.notebook)

        self.notebook.add(self.length_frame, text = 'Length')

        #Combobox
        self.measurements = StringVar()
        self.Combobox_Length_Left = ttk.Combobox(self.length_frame, textvariable = self.measurements, values = ('mm', 'cm', 'inch', 'ft', 'yd', 'm', 'km', 'mi'), width = 10,state=['readonly'])
        self.Combobox_Length_Left.current(5)
        self.measurements.trace('w', self.update_length)
        self.Combobox_Length_Left.grid(row = 2, column = 0, padx = 5, pady = 5, sticky = E)

        self.measurements1 = StringVar()
        self.Combobox_Length_Right = ttk.Combobox(self.length_frame, textvariable = self.measurements1, value = ('mm', 'cm', 'inch', 'ft', 'yd', 'm', 'km', 'mi'), width = 10,state = ['readonly'])
        self.Combobox_Length_Right.current(5)
        self.measurements1.trace('w', self.update_length)
        self.Combobox_Length_Right.grid(row = 2, column = 2, padx = 5, pady = 5, sticky = E)

        #Labels
        self.Conversion = Label(self.length_frame, text = 'Conversion:')
        self.Conversion.grid(row = 1, column = 0, padx = 5, pady = 5, sticky = W)

        self.Label_Blank = Label(self.length_frame, text = '')
        self.Label_Blank.grid(row = 1, column = 1, padx = 5, pady = 5, sticky = E)

        self.Label_To2 = Label(self.length_frame, text = 'to')
        self.Label_To2.grid(row = 2, column = 1, padx = 5, pady = 5, sticky = E)

       self.Label_To = Label(self.length_frame, text = 'to')
       self.Label_To.grid(row = 3, column = 1, padx = 5, pady = 5, sticky = E)

        #Entry Boxes
        self.Text_Length_Left = StringVar()
        self.Entry_Length_Left = ttk.Entry(self.length_frame, textvariable = self.Text_Length_Left,width = 13)
        self.Text_Length_Left.trace('w', self.update_length)
        self.Entry_Length_Left.grid(row = 3, column = 0, padx = 5, pady = 5)

        self.Text_Length_Right = StringVar()
        self.Entry_Length_Right = ttk.Entry(self.length_frame, textvariable = self.Text_Length_Right,width = 13, state='readonly')
        self.Entry_Length_Right.grid(row = 3, column = 2, padx = 5, pady = 5)

def main():
    root = Tk()
    app = GUI(root)
    root.title('Metric Calculator')
    root.resizable(False,False)
    root.mainloop()

main()

我只是想让第一个工作,但我正在努力。 谢谢你的帮助!

编辑:

问题是如何让第一个程序工作? 我得到的错误是self.measurements.trace('w', Logic.self.update_length()) AttributeError: type object 'Logic' has no attribute 'self'

2 个答案:

答案 0 :(得分:1)

您似乎对类方法的工作方式有了更基本的误解。如果不了解代码应该做什么,我想我只能给出一些基本建议(因为你的代码有很多错误)。

实例方法 - 您可以使用三种类型的方法:实例方法,类方法和静态方法。实例方法是最常见的种类。例如,我创建了一个定义一个点的类,并且有一个移动点的方法:

class Point:
    def __init__(self, x, y):
        self.position = [x, y]

    def shift(self, dx, dy):
        self.position[0] += dx
        self.position[1] += dy

shift方法是一个实例方法,因为它没有@classmethod@staticmethod装饰器(为了简单起见,我将忽略这些意思)。实例方法可能只对它所附加的类的实例进行操作,它不能对类本身进行操作。

因此,在此示例中,shift方法仅在Point的实例上运行

所以,如果我尝试:

point1 = Point(3, -5)
point1.shift(4, 4)
print(a.position)

我明白了:

[7, -1]

如果我尝试运行:

Point.shift(4, 4)

我将收到TypeError,因为Point没有shift的实例可供使用。

函数参数 -

def update_length(self, *args,measurements, measurements1, Text_Length_Left, Text_Length_Right):

会给你错误。如果您想处理可变数量的参数,或者如果函数采用您想要捆绑在一起的许多参数,则应该只使用解包(*args)。如果您使用*args然后尝试在后面指定更多位置参数,则会收到TypeError,因为Python在*args之后不期望更多位置参数。但是,您可以在*args之后使用关键字参数。

现在,在update_length中修改参数后,对函数的调用仍然会引发错误。目前,您对update_length的3次调用形式为:

Logic.self.update_length()

由于我对实例方法的解释,您首先需要删除self关键字。您只在类定义中使用此关键字,如果在其他任何地方使用,您将收到错误。此外,您需要在类Logic有权访问的某个位置实例化GUI。类似的东西:

class GUI:
    def __init__(self, root):
        ...
        self.logic = Logic(a, b, c, d)
        ...
        self.logic.update_length(e, f, g, h)

注意到您对update_length的当前调用未提供您需要的任何位置参数。您当前对update_length的定义需要4个位置参数(measurements, measurements1, Text_Length_Left, Text_Length_Right),但在调用函数时不会提供任何参数。

我希望这有用,我想你应该看一两个教程,然后回到你的代码。

答案 1 :(得分:0)

问题很简单:只需删除self

即可

self.measurements.trace('w', Logic.update_length())

当您调用静态函数时Class.Function()self未放置。查看代码时,必须创建类Logic,因为update_length()不是静态的,然后调用函数:

logic_class = Logic()
self.measurements.trace('w', logic_class.update_length())