【问题标题】:I pickled my tuple我腌制了我的元组
【发布时间】:2014-03-31 02:28:01
【问题描述】:

我还是 python 新手。我正在为一个更大的项目构建框架。这个程序让你想到一个圆形或方形,然后它会提出四个问题,然后决定一个答案。

我在框架的最后一步,但遇到了问题。我得到“未定义全局名称'qas1'”

getQuestion question 中的第 50 行 = 'qas' 全局名称 'qas' 未定义

这发生在我尝试腌制我的元组时。

这是我的加载程序,用于创建包含我的元组的泡菜文件:

import cPickle
import os

qas1 = [
('Are you more like Waffle or a Pancake'), 
('1. Waffle', 1, 0),
('2. Pancake', 0, 1)
]

qas2 = [
('Do you have a straight edge?'),
('1. Yes', 1, 0),
('2. No', 0, 1)
]

qas3 = [
('Are you simliar in shape to a lolipop?'),
('1. Yes', 0, 1),
('2. No', 1, 0)
]
qas4 = [
('Is the world rounded like a planet, or flat like a map?'),
('1. Rounded', 0, 1),
("2. Flat", 1, 0)
]

def hasFile():
    print 'I see the file'
    qas_file = open('qas.dat', 'r')
    qas1 = cPickle.load(qas_file)
    qas2 = cPickle.load(qas_file)
    qas3 = cPickle.load(qas_file)
    qas4 = cPickle.load(qas_file)
    qas_file.close
    confirmer()

def noFile():
    print 'I dont see a file...'
    saver()

def confirmer():
    print qas1
    print qas2
    print qas3
    print qas4

def saver():
    qas_file = open('qas.dat', 'w')
    print 'No worries, creating one now'
    cPickle.dump(qas1, qas_file)
    cPickle.dump(qas2, qas_file)
    cPickle.dump(qas3, qas_file)
    cPickle.dump(qas4, qas_file)
    qas_file.close
    print 'all done'

fname = "qas.dat"
if os.path.isfile(fname):
    hasFile()
else:
    noFile()

代码运行良好,但是当我尝试使用它创建的文件时遇到了问题。

import cPickle

#Counters
counterCircle = 0
counterSquare = 0

# tuples
def hasFile():
    print 'I see the file'
    qas_file = open('qas.dat', 'r')
    qas1 = cPickle.load(qas_file)
    qas2 = cPickle.load(qas_file)
    qas3 = cPickle.load(qas_file)
    qas4 = cPickle.load(qas_file)
    qas_file.close



#varibles Im made to assign
messageDisplayed = 0
question = 'beer'

#prints to screen   
def showQaA():
    print question[0]
    print question[1][0]
    print question[2][0]

#recieves and implements responses
def getResponce():
    global counterCircle
    global counterSquare
    global qas1, qas2, qas3, qas4
    ansew = raw_input('>> ')
    if ansew == "1":
        counterSquare = counterSquare + question[1][1]#(+1)
        counterCircle = counterCircle + question[1][2]#(+0)
    elif ansew == "2":
        counterSquare = counterSquare + question[2][1]#(+0)
        counterCircle = counterCircle + question[2][2]#(+1)
    print counterCircle
    print counterSquare


#Gets the current tuple infomation to display (Will be more advanced)
def getQuestion():
    global question
    if messageDisplayed == 0:
        question = qas1
    elif messageDisplayed == 1:
        question = qas2
    elif messageDisplayed == 2:
        question = qas3
    elif messageDisplayed == 3:
        question = qas4
    else:
        print 'youre screwd'

#figures out and prints results
def results():
    print "This is the circle results", counterCircle
    print "This is the square results", counterSquare
    if counterSquare < counterCircle:
        print "You are a circle!"
    elif counterSquare > counterCircle:
        print "You are a square!"
    else:
        print "You are the elusive squircle!"

#mainLoop currently set to 4 questions
hasFile()
while messageDisplayed <=3:
    getQuestion()
    showQaA()
    getResponce()
    messageDisplayed +=1
results()

我知道,要查看的代码很多。当程序第一次加载名称qas1 时,它重新确认它是一个元组,但是当我尝试将属性传递给getQuestion() 中的“问题”时:它忘记了它们是什么。任何理想有什么问题?

【问题讨论】:

  • 经典题名:)
  • 旁注:在hasFile 中,你写了qas_file.close。这导致对qas_fileclose 方法的引用,但不会调用它。在 python 关闭之前,您需要括号 (qas_file.close()) 或文件句柄。

标签: python tuples pickle


【解决方案1】:

在您的第二个文件中,qas[1-4] 都是 hasFile 函数的本地函数。让它们全局化,你的代码就可以工作了:

def hasFile():
   global qas1, qas2, qas3, qas4
   # etc

同样的错误出现在第一个代码中,但更难注意到 - 四个变量仍然只在函数中赋值 - 这 隐藏 同名的全局变量,使它们保持不变。但是,由于加载它们不会改变它们的内容,它似乎可以工作。

【讨论】:

    【解决方案2】:

    在 hasFile() 中,您正在设置 qas1、qas2、qas3 和 qas4 的值,但您没有将它们声明为全局优先,这意味着它们不在全局范围内设置。

    # tuples
    def hasFile():
        global qas1, qas2, qas3, qas4 # <-- global declaration
        print 'I see the file'
        qas_file = open('qas.dat', 'r')
        qas1 = cPickle.load(qas_file)
        qas2 = cPickle.load(qas_file)
        qas3 = cPickle.load(qas_file)
        qas4 = cPickle.load(qas_file)
        qas_file.close
    

    在您设置全局变量的每个函数中,您需要将它们显式声明为全局变量。见the answers to this question

    另外,在未来,考虑将值传递给函数而不是使用全局变量,这很容易出错,尤其是对于初学者。

    【讨论】:

    • 谢谢!我仍然不确定如何在函数中传递变量,Ima noob。
    • 现在我正试图摆脱我的全局变量。所有论坛似乎都建议像瘟疫一样避免它们。我能够将“问题”转向本地,但我的柜台遇到了麻烦。我唯一的理想是尝试将它们保存到 txt 文件或腌制它们,然后在循环重新启动时重新加载。这是一种不好的做法吗?
    • @user3479560 您可以将变量存储在程序之外、腌制或文本文件中,但这不是很有用,除非您想为将来的程序执行保存一些东西。我认为在主循环中管理它们效果最好。您可以让 getResponce() 为正方形或圆形返回不同的值。我建议你熟悉函数、参数、返回的东西等,这样你就可以看到有多少程序是结构化的,并让函数在没有全局变量的情况下一起工作。有很多东西要学,但你的代码会更有条理和可重用。祝你好运!
    • @user3479560 如果您正在寻找任何教程,我偏爱Learn Python the Hard Way 这本书。
    【解决方案3】:

    当您像在hasFile() 中所做的那样,只为像 qas 这样的变量分配一个新值时,您正在创建一个本地变量...而不是全局变量。确保在分配给它之前指定global qas

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 1970-01-01
      • 1970-01-01
      • 2017-08-14
      相关资源
      最近更新 更多