Python KeyError:无法通过导入的类访问全局

Python KeyError:无法通过导入的类访问全局,python,python-2.7,nameerror,global-scope,Python,Python 2.7,Nameerror,Global Scope,我试图计算化学方程式中元素的数量。我以某种方式创建的调试器无法访问程序中的全局变量。具体来说,我试图访问胡萝卜,但是左侧没有被添加到堆栈中。有什么想法吗 Debug.py class Debugger(object): def __init__(self,objs): assert type(objs)==list, 'Not a list of strings' self.objs = objs def __repr__(self):

我试图计算化学方程式中元素的数量。我以某种方式创建的调试器无法访问程序中的全局变量。具体来说,我试图访问
胡萝卜
,但是
左侧
没有被添加到堆栈中。有什么想法吗

Debug.py

class Debugger(object):
    def __init__(self,objs):
        assert type(objs)==list, 'Not a list of strings'
        self.objs = objs
    def __repr__(self):
        return '<class Debugger>'
    def show(self):
        for o in self.objs:
            print o,globals()[o] #EDIT
from Debug import Debugger

def directions():
    print 'Welcome to the chem Balancer.'
    print 'Use the following example to guide your work:'
    global left #LEFT IS GLOBAL
    left = 'B^6 + C^2 + B^3 + C^3 + H^9 + O^4 + Na^1'
    print left
    print "#Please note to use a 'hat' when entering all elements"
    print '#use only one letter elements for now'
# left = raw_input('enter formula:')  #enter formula to count
directions()

chem_stats = {}
chem_names = []
chem_names = []
chem_indy = []

for c in range(len(left)):
    if left[c].isalpha() and left[c].isupper():
        chars = ''
        if left[c+1].islower():
            chars += left[c]+left[c+1]
        else:
            chars += left[c]
        #print chars
        chem_indy.append(c)
        chem_names.append(chars)

carrots = [x for x in range(len(left)) if left[x]=='^']

debug = Debugger(['carrots','chem_names','chem_indy','chem_stats']) # WITHOUT LEFT
debug.show()
import sys
class Debugger(object):
    def __init__(self, module_name, objs):
        assert type(objs)==list,'Not a list of strings'
        self.objs = objs
        self.module_name = module_name
    def __repr__(self):
        return '<class Debugger>'
    def show(self):
        for o in self.objs:
            print o, sys.modules[self.module_name].__dict__[o]
import debugger as deb
a = 1
b = 2
d = deb.Debugger(__name__, ['a', 'b'])
print(d.objs)
d.show()
a = 10
b = 20
d.show()
错误消息:

Traceback (most recent call last):
  File "C:\Python27\#Files\repair\Chemical_Balancer.py", line 38, in <module>
    debug.show()
  File "C:\Python27\lib\site-packages\Debug.py", line 12, in show
    print o,globals()[o]
  File "<string>", line 1, in <module>
KeyError: 'carrots'
回溯(最近一次呼叫最后一次):
文件“C:\Python27\#Files\repair\Chemical\u Balancer.py”,第38行,在
debug.show()
文件“C:\Python27\lib\site packages\Debug.py”,第12行,在show中
打印o,全局()[o]
文件“”,第1行,在
关键错误:“胡萝卜”

关于
左侧变量上的特定错误:

当你说一个变量是全局变量时,python知道当使用它的名字时,它必须在全局名称空间中查找它。但是在代码
中,左
没有被分配到这样的名称空间中

如您所见,
left
被注释掉

#left = raw_input('enter formula:')  #enter formula to count
通过删除行首的
#
来取消注释,从而使
方向
函数中的行

global left
可以找到它,并且遵循的说明可以工作

关于实施: 允许调试器知道在何处查找变量(即在哪个模块中)的一种解决方案是,在创建模块时向调试器提供模块的名称。然后调试器对象可以通过sys.modules[module\u name]访问创建它的模块的全局变量

debugger.py

class Debugger(object):
    def __init__(self,objs):
        assert type(objs)==list, 'Not a list of strings'
        self.objs = objs
    def __repr__(self):
        return '<class Debugger>'
    def show(self):
        for o in self.objs:
            print o,globals()[o] #EDIT
from Debug import Debugger

def directions():
    print 'Welcome to the chem Balancer.'
    print 'Use the following example to guide your work:'
    global left #LEFT IS GLOBAL
    left = 'B^6 + C^2 + B^3 + C^3 + H^9 + O^4 + Na^1'
    print left
    print "#Please note to use a 'hat' when entering all elements"
    print '#use only one letter elements for now'
# left = raw_input('enter formula:')  #enter formula to count
directions()

chem_stats = {}
chem_names = []
chem_names = []
chem_indy = []

for c in range(len(left)):
    if left[c].isalpha() and left[c].isupper():
        chars = ''
        if left[c+1].islower():
            chars += left[c]+left[c+1]
        else:
            chars += left[c]
        #print chars
        chem_indy.append(c)
        chem_names.append(chars)

carrots = [x for x in range(len(left)) if left[x]=='^']

debug = Debugger(['carrots','chem_names','chem_indy','chem_stats']) # WITHOUT LEFT
debug.show()
import sys
class Debugger(object):
    def __init__(self, module_name, objs):
        assert type(objs)==list,'Not a list of strings'
        self.objs = objs
        self.module_name = module_name
    def __repr__(self):
        return '<class Debugger>'
    def show(self):
        for o in self.objs:
            print o, sys.modules[self.module_name].__dict__[o]
import debugger as deb
a = 1
b = 2
d = deb.Debugger(__name__, ['a', 'b'])
print(d.objs)
d.show()
a = 10
b = 20
d.show()
产生

['a', 'b']
a 1
b 2
a 10
b 20
如您所见,每次调用其
show
方法时,调试器都会打印变量的当前值


我发现了一些有用的信息。

关于
左侧变量的特定错误:

当你说一个变量是全局变量时,python知道当使用它的名字时,它必须在全局名称空间中查找它。但是在代码
中,左
没有被分配到这样的名称空间中

如您所见,
left
被注释掉

#left = raw_input('enter formula:')  #enter formula to count
通过删除行首的
#
来取消注释,从而使
方向
函数中的行

global left
可以找到它,并且遵循的说明可以工作

关于实施: 允许调试器知道在何处查找变量(即在哪个模块中)的一种解决方案是,在创建模块时向调试器提供模块的名称。然后调试器对象可以通过sys.modules[module\u name]访问创建它的模块的全局变量

debugger.py

class Debugger(object):
    def __init__(self,objs):
        assert type(objs)==list, 'Not a list of strings'
        self.objs = objs
    def __repr__(self):
        return '<class Debugger>'
    def show(self):
        for o in self.objs:
            print o,globals()[o] #EDIT
from Debug import Debugger

def directions():
    print 'Welcome to the chem Balancer.'
    print 'Use the following example to guide your work:'
    global left #LEFT IS GLOBAL
    left = 'B^6 + C^2 + B^3 + C^3 + H^9 + O^4 + Na^1'
    print left
    print "#Please note to use a 'hat' when entering all elements"
    print '#use only one letter elements for now'
# left = raw_input('enter formula:')  #enter formula to count
directions()

chem_stats = {}
chem_names = []
chem_names = []
chem_indy = []

for c in range(len(left)):
    if left[c].isalpha() and left[c].isupper():
        chars = ''
        if left[c+1].islower():
            chars += left[c]+left[c+1]
        else:
            chars += left[c]
        #print chars
        chem_indy.append(c)
        chem_names.append(chars)

carrots = [x for x in range(len(left)) if left[x]=='^']

debug = Debugger(['carrots','chem_names','chem_indy','chem_stats']) # WITHOUT LEFT
debug.show()
import sys
class Debugger(object):
    def __init__(self, module_name, objs):
        assert type(objs)==list,'Not a list of strings'
        self.objs = objs
        self.module_name = module_name
    def __repr__(self):
        return '<class Debugger>'
    def show(self):
        for o in self.objs:
            print o, sys.modules[self.module_name].__dict__[o]
import debugger as deb
a = 1
b = 2
d = deb.Debugger(__name__, ['a', 'b'])
print(d.objs)
d.show()
a = 10
b = 20
d.show()
产生

['a', 'b']
a 1
b 2
a 10
b 20
如您所见,每次调用其
show
方法时,调试器都会打印变量的当前值



我发现信息丰富且有用。

为什么要使用eval()?(我不是问,因为它是错的,只是想知道为什么要用它。)为了找到变量的值。是的,我用eval()做了一些尝试。我想我会找到它上面的文档。它会引发一个
KeyError
。不要使用全局变量,而是使用字典。为什么要使用eval()?(我不是问,因为它错了,只是想知道它为什么被使用。)为了找到变量的值。是的,我用eval()做了一些尝试。我想我会找到它上面的文档。它会引发一个
KeyError
。不要使用全局变量,而是使用字典。它在方向内,
global left;left='B^6+C^2+B^3+C^3+H^9+O^4+Na^1'
。我添加了一个代码示例,向您展示了它的工作原理,我理解并且可以工作,但我正在从其他地方导入模块。单独的类不知道globals()。感谢您的帮助。另一个解决方案是将globals作为构造函数传递,例如
调试器(mylist,globals())
,并让
\uuuuu init\uuuuu
访问它。但我认为这是一个调试器,而不是一个记录器。如果您将值传递给它,它将打印出变量创建时的值,而不是在调用
show
时。它位于方向内,
global left;left='B^6+C^2+B^3+C^3+H^9+O^4+Na^1'
。我添加了一个代码示例,向您展示了它的工作原理,我理解并且可以工作,但我正在从其他地方导入模块。单独的类不知道globals()。感谢您的帮助。另一个解决方案是将globals作为构造函数传递,例如
调试器(mylist,globals())
,并让
\uuuuu init\uuuuu
访问它。但我认为这是一个调试器,而不是一个记录器。如果您将值传递给它,它将打印出变量创建时的值,而不是调用
show
时的值。