连续脚本运行之间python中的vars()字典

连续脚本运行之间python中的vars()字典,python,dictionary,namespaces,Python,Dictionary,Namespaces,我正在尝试开发一个更简单的协议,用于在脚本运行之前、期间和之后记录工作环境的名称空间。显然,Python中唯一可用的功能是在运行脚本之前访问vars()、locals()或globals()字典,然后在运行脚本之后立即访问。这相当成功,因为我可以捕获名称空间的添加(通过它们的键),但我无法知道各种实体添加到字典的顺序。除了对列表进行手动排序以生成时间顺序列表之外,在尝试确定名称空间的创建顺序时,我是否忽略了什么。下面是vars()字典的前后快照的结果: >>> # vars()

我正在尝试开发一个更简单的协议,用于在脚本运行之前、期间和之后记录工作环境的名称空间。显然,Python中唯一可用的功能是在运行脚本之前访问vars()、locals()或globals()字典,然后在运行脚本之后立即访问。这相当成功,因为我可以捕获名称空间的添加(通过它们的键),但我无法知道各种实体添加到字典的顺序。除了对列表进行手动排序以生成时间顺序列表之外,在尝试确定名称空间的创建顺序时,我是否忽略了什么。下面是vars()字典的前后快照的结果:

>>> # vars() keys before running script
>>> vars_keys_0 = vars().keys()
>>> for key in vars_keys_0:
...     print('key: {:<15} - {}'.format(key,type(vars()[key])))
... 
key: __builtins__    - <type 'module'>
key: __name__        - <type 'str'>
key: pywin           - <type 'module'>
key: __doc__         - <type 'NoneType'>
key: __package__     - <type 'NoneType'>
>>> 
>>> # vars() keys after running script
>>> vars_keys_1 = vars().keys()
>>> for key in vars_keys_1:
...     print('key: {:<15} - {}'.format(key,type(vars()[key])))
...     
key: rand_pnts       - <class 'numpy.core.records.recarray'>
key: arr             - <class 'numpy.core.records.recarray'>
key: random          - <type 'module'>
key: extent_LRBT     - <type 'function'>
key: pnts            - <type 'list'>
    ..... snip ....
key: lineIntersect   - <type 'function'>
key: from_XsYs       - <type 'function'>
key: from_extent     - <type 'function'>
key: Xs              - <type 'list'>
key: vars_keys_0     - <type 'list'>
key: lineIntersect2  - <type 'function'>
>>>
字典是无序的,正如预期的那样,但我肯定遗漏了一些可以让人们按顺序收集名称空间添加的东西

编辑: 有了下面的额外建议,我尝试了这个简单的脚本来测试

import sys
def zipper(Xs,Ys):
  '''zip two lists'''
  return zip(Xs,Ys)
#--------------------------------------------------------------------
if __name__ == "__main__":
  _order = []
  _seen = set(vars())
  def trace_names(frame, event, arg):
    if event == 'call' and arg is None:
      # enter first frame, return 'local' trace
      return trace_names
    if event in ('line', 'return'):
      # (last) line in top-level frame executed
      _order.extend(frame.f_globals.viewkeys() - _seen)
      _seen.update(frame.f_globals)
  sys.settrace(trace_names)

  Xs = [0,0,2,2,0]
  Ys = [1,3,3,1,1]
  print('Zipped lists {}',format(zipper(Xs,Ys)))

  sys.settrace(None)
  print(_order)
不幸的是,结果更令人困惑: ('Zipped list{}','[(0,1)、(0,3)、(2,3)、(2,1)、(0,1)]) ['trace_names'、'u Seed'、'Xs'、'Ys'、'CmdTarget'、'Object'、'win32ui'、'default_闪烁体编码'、'app'、'Queue'、'thread_test'、'WindowOutputDocument'、'WindowOutputDocumentParent'、're'、'window'、'WindowOutputView闪烁体'、'test'、'string'、'WindowOutputView'、's闪烁体'、'docview'、'WindowOutputFrame'“,….“闪烁控制接口”,“闪烁显示”,“闪烁显示”,“闪烁显示”,“操作系统”]


如果def放置错误,请告知。

跟踪订单的唯一方法是使用完整跟踪。您可以使用,但必须将所有内容移动到
main()
函数中,因为您无法将跟踪器附加到当前帧,只能附加到新帧:

import sys

_order = []
_seen = set()

def trace_names(frame, event, arg):
    if event == 'call' and arg is None:
        # enter first frame, return 'local' trace
        return trace_names
    if event in ('line', 'return'):
        # (last) line in top-level frame executed
        _order.extend(frame.f_locals.viewkeys() - _seen)
        _seen.update(frame.f_locals)

sys.settrace(trace_names)

# run your script
main()

sys.settrace(None)
print(_order)

这只跟踪在下一个作用域中添加的局部变量的顺序;如果有任何函数修改全局变量,则通过从跟踪程序中检查
globals()
,您无法确定它们的确切顺序,而只能在整个组中进行。我不明白为什么顺序在这里很重要。很简单……我正在尝试制定流程运行的流程图。我使用流程图进行教学和文档记录,因此,顺序很重要。我现在在字典中手动排序差异。我的问题是,python“知道”事情何时完成……是否有一种方法可以从名称空间或其他地方访问此事件列表。我担心这会导致一切。。。['pnts','Ys','trace_names','u seen','Xs','fromrays','array','all','record','u typestr','types','fromfile','nt','byteorderconv','chararray','ndarray','isfileobj','get_剩余_大小','format_解析器','bytes','find_duplicate','recarray','fromstring','sb os','fromrecords','numfmt','arr','CmdTarget Object'win32ui',','默认闪烁编码','应用',…加上数百个。我在我的if name==“main”之后加载了以上内容:行与主代码后的最后两行block@Dan:将主代码放在函数中,如果需要,还可以跟踪
f_局部变量
。您现在正在跟踪顶级代码调用的所有全局变量。在主块中进行了尝试,我将其删除,并在defs之后将所有内容移动到…sys.settrace(trace_名称)之间…我的4行代码…sys.settrace(None)和我得到的以下代码,无论是否带有主块>>>('Zipped list{}','[(0,1),(0,3),(2,3),(2,1),(0,1)])['Xs','Ys','self','attr','o','msg','message','item','timeout','block','n','u Condition','u waiters','..'rc','len','str','end','currentPos','ancorpos','atEnd','text','start','cr','crBuff','addressCrBuff']1.我想我离我的目标越来越远了need@DanPatterson:更清楚一点;您必须启动一个新的作用域,此时您可以使用
main
函数(或者您需要将其作为单独的文件,并将原始脚本作为模块导入,此时您需要跟踪
f_globals
)。感谢您的帮助@Martijn,但在这一阶段,我认为在我的文档标题中收集名称空间会更快。
import sys

_order = []
_seen = set()

def trace_names(frame, event, arg):
    if event == 'call' and arg is None:
        # enter first frame, return 'local' trace
        return trace_names
    if event in ('line', 'return'):
        # (last) line in top-level frame executed
        _order.extend(frame.f_locals.viewkeys() - _seen)
        _seen.update(frame.f_locals)

sys.settrace(trace_names)

# run your script
main()

sys.settrace(None)
print(_order)