2017-04-26 59 views
-2

我有这样的代码,在Python 2.7:如何在一个类的另一个函数中调用一个函数的结果?

class App(ttk.frame): 
    def __init__(self, master=None): 
     ttk.Frame.__init__(self, master) 
     self.grid() 
     self.createWidgets() 

    def createWidgets(self): 
     self.okButton = ttk.Button(self, text = "OK", command = self.function2) 
     self.okButton.grid(column = 1, row = 1) 

    def function1(self, arg1, arg2): # function create fields in frame 
     self.arg1 = arg1 
     self.arg2 = arg2 

    def function2(self): #function calcule things with values of fields when Ok button is click 
     doing_thing_to(x, y, z, w) 

app = App() 
app.function1("x", "y") # Create first field 
app.function1("z", "w") # Create another field 
mainloop() 

当函数2呼唤我有一个错误信息:全局名称X,Y没有定义。

我试图把

x.get(); y.get() 
在函数2

却有着相同的错误。

我试图把

return arg1, arg2 
在功能1

,但有同样的问题。

如何在一个类另一个函数的函数调用的结果?

编辑:完整的代码,因为我不知道如何简化被理解:(功能冠军等champdouble有期函数作用和功能的回调有函数2的作用

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

from os import getcwd, path 
import Tkinter as tk 
from Tkinter import * 
import tkFileDialog as filedialog 
import shutil 
import ttk 
import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib 

matplotlib.style.use('ggplot') 
wd = getcwd() # working directory 

class Application(ttk.Frame): 
    def __init__(self, master=None): 
     ttk.Frame.__init__(self, master) 
     self.grid() 
     self.createWidgets() 

    def createWidgets(self): 
     self.quitButton = ttk.Button(self, text='Quitter', command=self.quit) 
     self.quitButton.grid(column=5, row=10, sticky=W) 
     self.okButton = ttk.Button(self, text="clic !", command=self.callback) 
     self.okButton.grid(column=4, row=10, sticky=W) 

    def champ(self, nom, defaut, col, ran, lab, collab, ranlab, largeur=7): 
     self.nom = nom 
     self.defaut = defaut 
     self.col = col 
     self.ran = ran 
     self.lab = lab 
     self.collab = collab 
     self.ranlab = ranlab 
     self.largeur = largeur 
     self.nom = StringVar() 
     nom = ttk.Entry(mainframe, width=largeur, textvariable=nom) 
     nom.insert(0, defaut) 
     if nom.bind('<FocusIn>'): 
      nom.delete(0, "end") 
     nom.grid(column=col, row=ran, sticky=W) 
     ttk.Label(mainframe, text=lab).grid(column=collab, row=ranlab, sticky=E) 

    def champdouble(self, nom1, defaut1, nom2, defaut2, col, ran, lab, lab2, collab, ranlab, largeur=7): 
     self.nom1 = nom1 
     self.defaut1 = defaut1 
     self.nom2 = nom2 
     self.defaut2 = defaut2 
     self.col = col 
     self.ran = ran 
     self.lab = lab 
     self.lab2 = lab2 
     self.collab = collab 
     self.ranlab = ranlab 
     self.largeur = largeur 
     nom1 = StringVar() 
     nom1 = ttk.Entry(mainframe, width=largeur, textvariable=nom1) 
     nom1.insert(0, defaut1) 
     nom1.grid(column=col, row=ran, sticky=W) 
     ttk.Label(mainframe, text=lab).grid(column=collab, row=ranlab, sticky=E) 
     nom2 = StringVar() 
     nom2 = ttk.Entry(mainframe, width=largeur, textvariable=nom2) 
     nom2.insert(0, defaut2) 
     nom2.grid(column=col+2, row=ran, sticky=W) 
     ttk.Label(mainframe, text=lab2).grid(column=collab+2, row=ranlab, sticky=E) 


    def on_entry_click(self, event): 
     """function that gets called whenever entry is clicked""" 
     global dirname 
     if file1.get() == 'Choisissez un fichier...': 
      file1.delete(0, "end") # delete all the text in the entry 
      dirinit = r'C:/' 
      dirname = filedialog.askopenfilename(parent=mainframe, initialdir=dirinit, title='Sélectionnez le fichier') 
      file1.insert(0, dirname) #Insert blank for user input 

    def on_entry_click1(self, event): 
     """function that gets called whenever entry is clicked""" 
     global dirname2 
     if file2.get() == 'Choisissez un fichier...': 
      file2.delete(0, "end") # delete all the text in the entry 
      dirinit = r'C:/' 
      dirname2 = filedialog.askopenfilename(parent=mainframe, initialdir=dirinit, title='Sélectionnez le fichier') 
      file2.insert(0, dirname2) #Insert blank for user input 

    def callback(self): 
     def traitement(fichier, debut, nif): 
      deb = int(debut.get()) 
      fin = int(nif.get()) 
      df = pd.read_csv(fichier, sep = '\t', engine = 'python', header = deb, skipfooter = fin) # Lecture des fichiers 
      df = df.rename(columns={'$Relations :NumZoneE': 'NumZoneE'}) # Renommage des entêtes de colonnes 
      df = df[(df.NumZoneE != df.NumZoneA)] # supression des intrazonaux 
      df = df[(df.NumZoneE <= 1289)] # supression des zones superieures a 1289 
      df = df[(df.NumZoneA <= 1289)] 
      df['OD_possible']=np.where(df['JRTA'] < 999999, 'oui', 'non') # creation d'une colonne OD_possible 
      df = pd.merge(df, dvol, on = ['NumZoneE', 'NumZoneA']) # jointure des tables avec dvol 
      dfg = df.groupby('OD_possible') # groupage selon oui ou non 
      return dfg 

     # Chemin d'acces vers les fichiers à traiter 
     dvol = r'c:\ceat_echange\1704_Test_maj_horaire_RERD_Sc2012\090721_DVOL_km.txt' 

     # Traitement de dvol 
     dvol = pd.read_csv(dvol, sep = '\t') # Lecture 
     dvol = dvol.rename(columns = {'ZONEO': 'NumZoneE', 'ZONED': 'NumZoneA'}) # Renommage entete 
     dvol = dvol[(dvol.DVOL != 0)] # Suppression intrazonaux 

     fig = plt.figure() 
     gss_oui = traitement(dirname, file1_deb, file1_fin).get_group('oui') 
     gss_non = traitement(dirname, file1_deb, file1_fin).get_group('non') 
     gac_oui = traitement(dirname2, file2_deb, file2_fin).get_group('oui') 
     gac_non = traitement(dirname2, file2_deb, file2_fin).get_group('non') 

     plt.hist([gss_oui[self.cettecolonne], gac_oui[self.cettecolonne]], range = (int(self.range1), int(self.range2)), bins = int(self.bins), label = [self.legend1l, self.legend2l]) 
     plt.legend(loc = 'best') 
     plt.title(self.titre) 
     plt.xlabel(self.axeXl, labelpad = 5) 
     plt.ylabel(self.axeYl) 
     plt.savefig(path.join(wd, self.sortiel)) 
     plt.show() 
     plt.close() 

if __name__ == '__main__': 
    app = Application() 
    style = ttk.Style() 
    style.configure("BW.TEntry", foreground="grey", background="white") 
    style.configure("BW1.TEntry", foreground="black", background="white") 
    app.master.title('Comparaison de fichiers') 

    mainframe = ttk.Frame(app, padding="3 3 12 12") 
    mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) 
    mainframe.columnconfigure(0, weight=1) 
    mainframe.rowconfigure(0, weight=1) 

    # construction du champ file1 
    file1 = StringVar() 
    file1_deb = StringVar() 
    file1_fin = StringVar() 
    file1 = ttk.Entry(mainframe, width=20, style="BW.TEntry") 
    file1.insert(0, 'Choisissez un fichier...') 
    file1.grid(column=2, row=1, sticky=W) 
    file1.bind('<FocusIn>', app.on_entry_click) 
    ttk.Label(mainframe, text="Fichier n° 1 : ").grid(column=1, row=1, sticky=E) 
    file1_deb = ttk.Entry(mainframe, width=5, textvariable=file1_deb) 
    file1_deb.insert(0, "26") 
    file1_deb.grid(column=4, row=1, sticky=W) 
    ttk.Label(mainframe, text="ligne de début").grid(column=3, row=1, sticky=E) 
    file1_fin = ttk.Entry(mainframe, width=5, textvariable=file1_fin) 
    file1_fin.insert(0, "1307") 
    file1_fin.grid(column=6, row=1, sticky=W) 
    ttk.Label(mainframe, text="lignes de fin à supprimer").grid(column=5, row=1, sticky=E) 

    # construction du champ file2 
    file2 = StringVar() 
    file2_deb = StringVar() 
    file2_fin = StringVar() 
    file2 = ttk.Entry(mainframe, width=20, style="BW.TEntry") 
    file2.insert(0, 'Choisissez un fichier...') 
    file2.grid(column=2, row=2, sticky=W) 
    file2.bind('<FocusIn>', app.on_entry_click1) 
    ttk.Label(mainframe, text="Fichier n° 2 : ").grid(column=1, row=2, sticky=E) 
    file2_deb = ttk.Entry(mainframe, width=5, textvariable=file2_deb) 
    file2_deb.insert(0, "26") 
    file2_deb.grid(column=4, row=2, sticky=W) 
    ttk.Label(mainframe, text="ligne de début").grid(column=3, row=2, sticky=E) 
    file2_fin = ttk.Entry(mainframe, width=5, textvariable=file2_fin) 
    file2_fin.insert(0, "1307") 
    file2_fin.grid(column=6, row=2, sticky=W) 
    ttk.Label(mainframe, text="lignes de fin à supprimer").grid(column=5, row=2, sticky=E) 

    app.champ("cettecolonne", "JRTA", 2, 3, "Champ à comparer :", 1, 3, 20) 

    app.champ("titre", "Titre du graphique", 2, 4, "Titre du graphique :", 1, 4, 20) 

    app.champdouble("range1", 0, "range2", 100, 2, 5, "Xmin :", "Xmax :", 1, 5) 
    app.champ("bins", 20, 2, 6, "Nombre d'intervalle :", 1, 6, 5) 
    app.champdouble("legend1", "file1", "legend2", "file2", 2, 7, "Légende du fichier n°1 :", "Légende du fichier n°2 :", 1, 7, 20) 
    app.champ("axeX", "Axe des X", 2, 8, "Nom de l'axe des x :", 1, 8, 20) 
    app.champ("axeY", "Axe des Y", 2, 9, "Nom de l'axe des y :", 1, 9, 20) 
    app.champ("sortie", "image.png", 2, 10, "Nom du .png sauvegardé :", 1, 10, 20) 

    for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5) 
    mainloop() 
+0

侧面说明:有没有名为'Object'的内建类。你的意思是'物体'吗?此外,根据PEP8,用户定义的类应使用CapWords进行命名,从而使类名称为“App”,而不是“app”。 – ShadowRanger

+0

对不起,我没有花时间做一个正式的代码,它是一个错误,这个错误的答案更多的问题。这是我的第二个问题,所以我学习如何提出正确的问题。 ttk.frame的类继承。 – Pataclop

回答

2

您保存的值"x""y"self.arg1function1()self.arg2,所以你必须在function2()也指他们通过这些名字:

class App(Object) 
    def function1(self, arg1, arg2): 
     self.arg1 = arg1 
     self.arg2 = arg2 

    def function2(self): 
     print(self.arg1, self.arg2) 

app = App() 
app.function1("x", "y") 
app.function2() 

注意由于您使用的一类,你必须创建一个实例先用app = App()(我改名为你appApp,它是用大写字母开始的类名是个好主意)。

在这一点上它可能会更好使用Python的“神奇” __init__,它允许你将这些传递给当它创建的实例,而不是调用一个单独的function1()

class App(Object) 
    def __init__(self, arg1, arg2): 
     self.arg1 = arg1 
     self.arg2 = arg2 

    def function(self): 
     print(self.arg1, self.arg2) 

app = App("x", "y") # This calls App.__init__(app, "x", "y") 
app.function() 
+0

感谢您的回答。我的课是一个带__init__的Tk.frame。编辑我的职位,因为函数2期函数调用2型动物的结果,所以self.arg1/self.arg2调用函数2没有运行。如果没有完整的代码,我不知道我是否清楚。 – Pataclop

+0

@Pataclop编辑后的问题实际上是没有意义的......你是什么* *实际努力实现?如果你只是想在'函数2打印字符()',然后用绳子代替变量 –

+0

是的,我同意,所以我复制完整的代码,因为我没能图式化它。 – Pataclop

相关问题