我正在开发一个Python模块,它充当旧游戏脚本语言的解释器。在途中我发现了很多我需要的变量,模块的顶部看起来像这样:
from mufdatatypes import *
debugline=0
code=[]
debugline=0 #Line where something interesting starts
currentline=0 #Line where we currently are
infunc=0 #Need to know if we're in a function or not.
iflevel=0 #Need to track how far into ifs we are
inelse=0 #If we're in an if, have we already done an else?
looplevel=0 #Also need to know how many loops deep we're in
instrnum=0
charnum=0
gvarlist=[ "me": mufvariable(dbref(2)) , "loc" : mufvariable(dbref(0)) , "trigger" : mufvariable(dbref(-1)) , "command": mufvariable("") ]
item=''
structstack=[]
这变得非常混乱。在执行大多数定义的函数的开头,它看起来像这样:
def mufcompile(rawcode, primstable):
"""Compiles a source string into a list of instructions"""
global source
global code
global debugline
global currentline
global code #The actual instructions will be stored here.
global infunc #Need to know if we're in a function or not.
global iflevel #Need to track how far into ifs we are.
global inelse #If we're in an if, have we already done an else?
global looplevel #Also need to know how man loops deep we're in.
global addresstable #This will hold a table of function addresses.
global structstack #This list stack will be used to hold status info as we go further down complex statements
global instrnum #Number of instruction. Important for moving the EIP.
global vartable #Table of variables. Dictionary.
global charnum #Character in the line we're at.
global item
我有一种感觉,我是以一种不正确的方式做到这一点,也许,对于真正知道他们在使用Python做什么的人来说,这很有趣。我知道变量可以在现场声明,但是如果我写的那个上面的任何函数都引用了这些函数,它们就不会编译,对吧?我也有点担心全球化的全球化程度。导入此模块的模块是否可以访问这些变量?我不希望他们这样做。
答案 0 :(得分:2)
最好是创建一个字典或类来存储不同变量的值,至少如果它们是相关的。然后将此对象作为参数传递给函数,您可以摆脱全局变量。无论如何,您可以查看this question以详细了解global
关键字的工作原理。
答案 1 :(得分:2)
其中一些看起来应该在一个对象中,但其他看起来你需要重构代码。
对象中应该是source
,lineno
之类的东西,一旦它们在一个对象中,那么你有两个选择:要么将该对象传递给每个函数,要么更好,使您的函数方法,以便他们可以“看到”数据作为属性。
如下所示:
class Parser(object):
def __init__(self, source):
self._source = source
self._lineno = 0
...
def parse_next_line(self, ...):
self._lineno += 1
...
明白了吗?然后通过执行以下操作来运行代码:
source = ....
parser = Parser(source)
parser.parse_next_line(...)
但是还有其他一些东西,比如inelse
和looplevel
。这些东西不应该存在于“外部”单一功能中,你需要更多地思考如何组织代码。很难说更多,因为我看不到所有的细节,我也不想批评太多,因为你想到这个很好......
答案 2 :(得分:0)
请记住,如果您需要更改它的全局值,您只需要将变量声明为全局变量。可以从任何地方读取/使用顶级变量。