0

rlg としてインポートされるプログラムのボタン インターフェイスを作成しようとしています。rlg には、シミュレーションの世代が進むにつれて 2 つの変数を測定および更新できるライブ グラフ システムがあります。これら 2 つの変数を選択できるようにしたいので、rlg の main() メソッドで、ドロップダウン メニューの各文字列選択がキーとして機能する辞書「graphLines」を作成しました。ただし、アクセスしてエラーメッセージを取得できないようです: AttributeError: 'function' object has no attribute 'graphLines'. 誰が私が間違っているかを見ることができますか?

from Tkinter import *
import runlivegraph3 as rlg

def run():
    rlg.main()

def setLine1(name):
    rlg.main.Line1data = rlg.main.graphLines[name] #graphlines is a dictionary in runlivegraph3 main method

def setLine2(name):
    rlg.main.Line2data = rlg.main.graphLines[name]


root = Tk()

var1 = StringVar()
var1.set("select graph line 1 data") #initial variable in drop down menu, each string is a key in the graphLines dictionary
op1 = OptionMenu(root, var1, 'Political attacks in turn',
                 'Ethnic attacks in turn',
                 'Total attacks in turn',
                 'Ethnic attacks as a percentage of total attacks',
                 'Political attacks as a percentage of total attacks',
                 'Group 1 ethnic antagonism',
                 'Group 2 ethnic antagonism',
                 command = setLine1).pack()


var2 = StringVar()
var2.set("select graph line 2 data") #initial variable in drop down menu
op2 = OptionMenu(root, var2, 'Political attacks in turn',
                 'Ethnic attacks in turn',
                 'Total attacks in turn',
                 'Ethnic attacks as a percentage of total attacks',
                 'Political attacks as a percentage of total attacks',
                 'Group 1 ethnic antagonism',
                 'Group 2 ethnic antagonism',
                 command = setLine2).pack()
butn = Button(root, text = 'run',  command = run)
butn.pack()
root.mainloop() 

これは、Tkinter ボタン プログラムでインポートしているプログラムの main() 関数です。

from matplotlib.pylab import *
import sys, random, time, csv
def main():

IDs = {}
boardDims = (20,20)
Line1data = None
Line2data = None
turnLimit = 40
pause = 0.0001

ethnicPred = []
politicalPred = []
totalAttacks = []
generation = []
data1 = []
data2 = []
data3 = []
ethAnt1 = []
ethAnt2 = []
polAnt1 = []
polAnt2 = []
EthnicAttacksInTurn = []
PoliticalAttacksInTurn = []
TotalAttacksInTurn = []
ProportionEth = []
ProportionPol = []


board = make_board(boardDims)

finallyAddAgents(IDs, board, boardDims)
splitAgents(IDs)
setRemainingPolitics(IDs)
setPoliticalAntagonism(IDs)

turn = 0
line1, = plot(turn, 0, 'b')  #initialise lines
line2, = plot(turn, 0, 'r')
running = 1
while running:
    ion()   #sets up graph base and axes
    axes()
    xlim(0,turnLimit)
    ylim(0,30)
    if turn == turnLimit: running = 0
    print_board3(IDs, board, boardDims)
    print 'turn ', str(turn)
    polAttackTurn = []
    ethAttackTurn = []
    AllAgentsPerformActions(IDs, board,turn,ethnicPred, politicalPred,
                            totalAttacks,polAttackTurn,ethAttackTurn)

    totalAttackTurn = sum(ethAttackTurn) + sum(polAttackTurn)
    if totalAttackTurn != 0:
        propEth = (sum(ethAttackTurn)*100)/totalAttackTurn
        propPol = (sum(polAttackTurn)*100)/totalAttackTurn        
    if totalAttackTurn == 0:
        propEth = 0
        propPol = 0
    TotalAttacksInTurn.append(totalAttackTurn)
    EthnicAttacksInTurn.append(sum(ethAttackTurn))
    PoliticalAttacksInTurn.append(sum(polAttackTurn))
    ProportionEth.append(propEth)
    ProportionPol.append(propPol)



    k =  sum(politicalPred)
    j = sum(ethnicPred)
    #f = sum(totalAttacks)
    #print k, j, f
    data1.append(j)
    data2.append(k)
    #data3.append(f)
    generation.append(turn)
    for agent in IDs.values():
        if agent.group == '1':
            ethAnt1.append(agent.antagonism['2'])
            break
    for agent in IDs.values():
        if agent.group == '2':
            ethAnt2.append(agent.antagonism['1'])
            break
    for agent in IDs.values():
        if agent.politics == 'A':
            polAnt1.append(agent.polAntagonism['B'])
            break
    for agent in IDs.values():
        if agent.politics == 'B':
            polAnt2.append(agent.polAntagonism['A'])
            break
    #this is the dictionary i am trying to access from the Tkinter button program
    graphLines = {'Political attacks in turn':sum(polAttackTurn),
              'Ethnic attacks in turn':sum(ethAttackTurn),
              'Total attacks in turn':totalAttackTurn,
              'Ethnic attacks as a percentage of total attacks': propEth,
              'Political attacks as a percentage of total attacks': propPol,
              'Group 1 ethnic antagonism': ethAnt1[-1],
              'Group 2 ethnic antagonism': ethAnt2[-1]}

        line1.set_ydata(append(line1.get_ydata(), Line1data))
        line1.set_xdata(append(line1.get_xdata(), turn))
        line2.set_ydata(append(line2.get_ydata(), Line2data))
        line2.set_xdata(append(line2.get_xdata(), turn))
        draw()
        turn += 1 
4

1 に答える 1

0

コメントを回答に変えたほうがいいと思ったので、ここに行きます。

変数と属性の違いが分からなくなってきたので、例を挙げて違いを説明します。あなたの質問は、実際にインポートすることではなく、スコープとオブジェクト指向プログラミング (OOP) に関するものです。

(例 1)関数内でローカル変数を設定するには、次のようにします。

def spam():
    eggs = 5

(例 2)関数オブジェクトに属性を設定するには (通常はあまり論理的ではありません)、次のようにします。

def spam():
    pass
spam.eggs = 5

これらは似ているように見えるかもしれませんが、その効果は大きく異なります。最初の例でeggsは、 は関数内のローカル変数ですspam。ローカル変数は、その定義関数内でのみ作成、アクセス、および変更されます。

def spam():
    eggs = 5
print spam.eggs

エラーになりますが、

def spam():
    pass
spam.eggs = 5
print spam.eggs

しない。2 番目の例でeggsは、関数 (オブジェクト) の属性ですspam。オブジェクトのメソッド内またはオブジェクト外の両方で作成、アクセス、および変更できますが、ローカル変数として関数自体内ではできませ(関数は完全に定義されるまでその存在を認識しないため)。したがって、次の場合はエラーが発生します。

def spam():
    print eggs
spam.eggs = 5
spam()

eggsはローカル変数ではなく属性であるためです。

OOP に精通している場合は、次の拡張があります。

最初の例は次と同等です。

class Spam(object):
    def __init__(self):
        eggs = 5

一方、2 番目の例は次のようになります。

class Spam(object):
    def __init__(self):
        self.eggs = 5

OOP に関して言えば、違いは単純に、1 つ目はローカル変数を設定し、2 つ目はインスタンス変数を設定することです。最初のクラスでやろうとしてもSpam().eggs意味がありませんが、2 番目のクラスではできます。

ついに、

問題を解決するには、必要な変数を関数の外で定義するか、globalキーワードを使用して変数がグローバルであることを示します。使用例:

def spam():
    global eggs
    eggs = 5
spam()
print eggs  # Prints 5
于 2012-08-06T17:22:13.780 に答える