所以在下面的代码中我得到tb没有定义,但是当我使用pdb时,我看到tb已定义,并且本地也在populatingNodeSlotPort函数的本地范围内填充了一堆值。
这是scenarioUniform1PartA.py文件
import json
import sbt
import sys
sys.path.append('staging/mgmt/ifc/ishell/')
def Get_Test_Block():
import inspect
for Entry in inspect.stack():
Args = inspect.getargvalues(Entry[0])
# print 'Args is ', Args
if Args[3].has_key('self') and hasattr(
Args[3]['self'],'Test_Block_Yaml_Data'):
return Args[3]['self']
raise ValueError, 'Could not determine current test block.'
def load(scenarioObj):
scenarioInit(scenarioObj)
log = logging.getLogger('sbt')
vmTopo = []
readScale(scenarioObj)
tb = Get_Test_Block()
tb.Harness_Object.Build_Mo_Objects()
# manipulating values of some variables here
return locals()
接下来是scenarioUniform1.py文件
from scenarioUniform1PartA import *
def populatingNodeSlotPort(scenarioObj):
for k,v in load(scenarioObj).items():
vars()[k] = v
tbType = 'unknown'
import pdb;pdb.set_trace()
tbType = tb.Nodes.Get_Nodes_By_Type(Defines.NODE_TYPE_LEAF)[0]['Mode']
pdb trackback
> /local/vchauhan/updatedBox/mgmt.git/test/system/sbt/scenarioUniform1.py(28)populatingNodeSlotPort()
-> tbType = tb.Nodes.Get_Nodes_By_Type(Defines.NODE_TYPE_LEAF)[0]['Mode']
(Pdb) print tb
<Classes_ScenarioLoad.ScenarioLoad object at 0x49dab50>
(Pdb) locals()['tb']
<Classes_ScenarioLoad.ScenarioLoad object at 0x49dab50>
(Pdb) n
NameError: "global name 'tb' is not defined"
> /local/vchauhan/updatedBox/mgmt.git/test/system/sbt/scenarioUniform1.py(28)populatingNodeSlotPort()
供参考
(Pdb) locals()
{'vmTopologyFileName': '/tmp/vmm_topos.yml', 'new_size': 1, 'nodeToBeDecomCom': 3, 'vmTopo': [{'VCenter_List': [{'Name': 'vserver51-222'}], 'ESX_List': [{'VCenter': 'vserver51-222', 'Name': 'esx51-443'}, {'VCenter': 'vserver51-222', 'Name': 'esx51-444'}], 'Connection_List': [{'Dest': 'leaf1', 'Source': 'esx51-443'}, {'Dest': 'leaf2', 'Source': 'esx51-444'}], 'VShield_List': [{'Name': 'vshield51-222'}], 'VM_List': [{'Name': 'c6-222'}, {'Name': 'd6-222'}]}], 'size': 4, 'vmTopoName': 'vchauhan', 'log': <logging.Logger instance at 0x30abb90>, 'scenarioObj': <sbt.Scenario object at 0x337c790>, 'nodeId': 1, 'nodeToBeShutdown': 2, 'clusterShardInstanceStepCounter': 4, 'unWiredIfcCount': 2, 'tb': <Classes_ScenarioLoad.ScenarioLoad object at 0x49dab50>, 'applyOnIfc': 1, 'halfUnWiredIfcCount': 2, 'Command_String': '../../tools/res.py sh -s vchauhan', '__exception__': (<type 'exceptions.NameError'>, "global name 'tb' is not defined"), 'tbType': 'unknown', 'Output': '--------------------------------------------------------------------------------\n6 are in production\n--------------------------------------------------------------------------------\nDevice Name Type IP Reserved By Other Info\n--------------------------------------------------------------------------------\nvserver51-222 vcenter 192.168.82.249 vchauhan \nesx51-443 esx 192.168.81.145 vchauhan multiPnic\nesx51-444 esx 192.168.81.146 vchauhan multiPnic\nvshield51-222 vshield 192.168.81.162 vchauhan \nc6-222 pc 0.0.0.0 vchauhan \nd6-222 pc 0.0.0.0 vchauhan \n--------------------------------------------------------------------------------\n\n', 'wiredIfcCount': 1, 'wiNodeStepCounter': 20, 'i': 2, 'k': 'applianceClusterPolStepCounter', 'temp_size': 1, 'v': 100, 'pdb': <module 'pdb' from '/usr/lib64/python2.6/pdb.pyc'>, 'applianceClusterPolStepCounter': 100}
答案 0 :(得分:1)
首先,您遇到调试问题这一事实正是不应该这样做的原因。为什么要把变量注入locals()
呢?只需使用dict
直接提供给您的load(scenarioObj)
。
my_dict = load(scenarioObj)
my_dict['tb'].Nodes.whatever...
您应该同样远离return
中的locals()
load
。 明确地以任何形式返回您需要的数据... dict,namedtuple
,自定义类。不管。
发生这种情况的原因是你“擅长”翻译。考虑两个看似等效的函数:
def f():
x = []
x.append(1)
def g():
locals()['x'] = [] #n.b. locals() is equivalent to vars()
x.append(1)
同样的事,对吧?不。
dis.dis(f)
2 0 BUILD_LIST 0
3 STORE_FAST 0 (x)
3 6 LOAD_FAST 0 (x) #NOTE: loading x as a LOCAL
9 LOAD_ATTR 0 (append)
12 LOAD_CONST 1 (1)
15 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
18 POP_TOP
19 LOAD_CONST 0 (None)
22 RETURN_VALUE
dis.dis(g)
2 0 BUILD_LIST 0
3 LOAD_GLOBAL 0 (locals)
6 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
9 LOAD_CONST 1 ('x')
12 STORE_SUBSCR
3 13 LOAD_GLOBAL 1 (x) #NOTE: loading x as a GLOBAL
16 LOAD_ATTR 2 (append)
19 LOAD_CONST 2 (1)
22 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
25 POP_TOP
26 LOAD_CONST 0 (None)
29 RETURN_VALUE
请参阅两个注释行 - 第一个函数认为x
是本地的,第二个认为x
是全局。 python解释器假设您在调用方法之前未在函数范围内明确地为x
分配了某些内容,必须引用全局。值得注意的是,当它编译函数时,它决定x
是本地的还是全局的,这在你实际调用之前就已经完成了。因此,解释器绝对无法在当时检测到变量动态注入locals
。
答案 1 :(得分:1)
您确定要使用从函数返回的值自动修改局部变量等游戏吗?
为什么不返回dict
并使用其中的值:
def load(scenarioObj):
return {'tb': tb, ...}
...
def populatingNodeSlotPort(scenarioObj):
data = load(scenarioObj)
tb = data['tb']
tbType = tb.Nodes.Get_Nodes_By_Type(Defines.NODE_TYPE_LEAF)[0]['Mode']
答案 2 :(得分:0)
如果要动态修改变量,请使用globals
代替locals
。修改locals
字典并不能保证做任何事情。在CPython中,它肯定没有做任何事情。