我将元组序列化了

10 投票
3 回答
1535 浏览
提问于 2025-04-18 00:37

我还是个Python新手,正在为一个大项目搭建框架。这个程序会让你想象一个圆形或方形,然后问你四个问题,最后给出一个答案。

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

在 getQuestion 的第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() 中将属性传递给 'question' 时,它却忘记了这些属性是什么。有人知道这是什么问题吗?

3 个回答

1

在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

每次在函数里设置全局变量时,你都需要明确地声明它们是全局的。可以参考这个问题的答案

另外,将来可以考虑把值传递给函数,而不是使用全局变量,因为全局变量容易出错,尤其是对初学者来说。

1

当你像在 hasFile() 里那样给一个变量,比如 qas,赋一个新值时,其实你是在创建一个局部变量,而不是全局变量。要确保在直接给它赋值之前,先写上 global qas,这样才能让它在全局范围内使用。

4

在你的第二个文件中,qas[1-4]都是局部变量,只在hasFile这个函数里有效。把它们改成全局变量,你的代码就能正常运行了:

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

第一个代码里也有同样的问题,不过不太容易发现——这四个变量仍然只在函数内部被赋值,这样就“遮盖”了同名的全局变量,导致全局变量的值没有改变。不过,因为加载这些变量时并不期望它们的内容会改变,所以看起来好像是正常工作的。

撰写回答