使用两个不同的函数后,全局变量不会保持其状态

2024-10-02 20:39:34 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我现在有麻烦了好几天。基本上,我正在为一种使用python创建的语言编写编译器。我们已经完成了sintax和lexic部分,现在正在创建目录过程和变量表(符号表)。在我的Yacc文件中,我有:

Yacc.py

import ply.yacc as yacc
import sys

tokens = Lex.tokens
#Global variables
procs = { }
current_fid = ""

# add new value to the procedure directory
def add_procs_to_dict(fid, ftipo, fparams, fdict):
    proc_dict = {}
    proc_dict[fid] = {
        'Tipo' : ftipo,
        'Params' : fparams,
        'Var_dict' : fdict
    }
    return proc_dict

# add new variable value to the procedure directory
def add_vars_to_dict(vid, vtipo, vparams):
    var_dict = {
        'Nombre' : vid,
        'Tipo' : vtipo,
        'Params' : vparams
        }
    print(current_fid)
    print(procs)    
    return proc_dict


# Parsing Rules    
def p_juego(p):
    '''Juego : JUEGO ID DOSP JuegoA JuegoB MainProgram'''
    current_fid = p[2]
    procs = add_procs_to_dict( p[2], p[1], 'void', {})

def p_vars(p):
    '''Vars : VAR ID COR_I Exp COR_D VarSizeA Vars2 DOSP Tipo PCOMA'''
    add_vars_to_dict( p[2], p[9], p[4])

这里需要注意的重要一点是,我正在创建一个变量,它将当前ID(名为current_fid,它是插入字典中的最后一个过程的名称)和一个字典变量(名为procs,即过程/函数目录)保存为全局范围。在

当解析器输入解析规则p_juego(p):(假设它所输入的代码是正确的,并且我已经单独运行了它),它假设将它在解析器进程中找到的值设置为变量(current_fidprocs)。它确实设置了正确的值。我可以打印函数内部的变量并返回期望值。在

一旦解析器退出函数p_juego(p)并进入另一个类似p_vars(p)的函数(此函数将插入全局目录的最后一个过程/函数的符号表写到字典中),全局变量(current_fidprocs)就没有值了。在p_vars(p)内有2个打印,始终为变量显示null。在

我对python还比较陌生,也许我对这门语言有些欠缺。我的意图是,如果我在所有事情之前(在代码的顶部)定义一个变量,那么使用这些“全局”变量的函数将更新它们的值并始终保留它们,即使另一个函数试图访问它们。 我尝试在一个名为语义.py但变量的值在先前设置值的函数之外始终为null。在

我错过了什么?在


Tags: to函数目录addid过程defproc
3条回答

为了避免像这样的问题,并且更明确地说,我建议您使用一个类。然后你可以使用自变量在类方法调用之间保存信息。在

感谢大家的快速反应。我确实按照你们大多数人的建议做了另一个类,但是我没有保留我的全局值的原因是函数的调用顺序出乎我的意料。PLY库使用自下而上的过程来导航sintax树。实际上,函数是在even设置之前读取值时调用的。在

我很感谢大家的回复,因为这是我在SO中的第一篇文章,每个回复我答案、问我问题甚至更正我帖子的人都鼓励我继续使用这个网站。在

再次感谢。在

[编辑] 你的代码有很多问题。在

首先:

您的函数add_vars_to_dict,定义并分配一个您永远不会使用的dict(var_dict),并尝试返回函数作用域中不存在的内容(proc_dict)。在

第二:

每次调用函数时,函数都会重新分配dict的值,这会使您丢失procs的先例值

procs = add_procs_to_dict( p[2], p[1], 'void', {})

然而,正如majodi建议的那样,通常可以使用类来解决全局变量问题,在类中使用实例变量,而不是全局变量

像这样的东西:

^{pr2}$

相关问题 更多 >