python,ipython运行交互式脚本

python,ipython运行交互式脚本,python,pandas,ipython,Python,Pandas,Ipython,我有一个名为“poc.py”的脚本,它接受一个位置命令行参数“inputfile.txt”。poc.py脚本使用argparse处理位置命令行参数,然后将args dict传递给main()。一旦进入main(),我就读取输入文件,进行一些处理,创建一个pandas数据帧,最后绘制数据。我在操作数据帧和控制结果图的精确格式方面遇到困难,因此我想尝试ipython以交互方式探索这一点,看看是否能够更好地掌握处理pandas/matplotlib的“pythonic”方法 所以我尝试使用ipytho

我有一个名为“poc.py”的脚本,它接受一个位置命令行参数“inputfile.txt”。poc.py脚本使用
argparse
处理位置命令行参数,然后将args dict传递给
main()
。一旦进入
main()
,我就读取输入文件,进行一些处理,创建一个
pandas数据帧,最后绘制数据。我在操作数据帧和控制结果图的精确格式方面遇到困难,因此我想尝试ipython以交互方式探索这一点,看看是否能够更好地掌握处理pandas/matplotlib的“pythonic”方法

所以我尝试使用ipython并运行脚本,但我无法让ipython保留脚本的名称空间

我试过这个:

$ ipython --pylab -i poc.py inputfile.txt
它可以很好地运行我的脚本,并显示绘图(即使没有阻塞
plt.show()
调用),但是当脚本完成时,
ipython who
whos
命令说
交互式命名空间为空。同样,如果我首先进入ipython外壳,然后执行以下操作:

In [2]: run poc.py inputfile.txt
当脚本完成时(同样,大量的输出和绘图显示),我得到了相同的结果:一个空的交互式名称空间

在理解如何运行外部脚本并使用ipython以交互方式浏览脚本中的数据/对象方面,我缺少什么

下面是如何设置我的脚本(
poc.py
)的一个简单示例:

import numpy as np
import matplotlib as plt
import pandas as pd

# etc ...more libraries and custom functions here...

def main(args):
  data = np.genfromtxt(args.inputfile)

  # (omitted)...more data processing / manipulation...
  pdata = pd.DataFrame(data)

  # (omitted)...more data processing / manipulation...
  plt.plot(pdata)

  # (omitted)...some formatting of the matplotlib/axes/figure objects
  plt.show()


if __name__ == '__main__':
  parser = argparse.ArgumentParser(description='''some program...''')
  parser.add_argument('inputfile', help='path to input file')
  args = parser.parse_args()
  main(args)

这里的问题是
data
pdata
不在脚本的命名空间中;它们位于已经运行并完成的函数的本地命名空间中

如果你想在事后检查它们,你需要把它们存放在某个地方。例如:

    # ...
    plt.show()

    return data, pdata, plt

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='''some program...''')
    parser.add_argument('inputfile', help='path to input file')
    args = parser.parse_args()
    data, pdata, plt = main(args)
(或者,您可以将main的所有变量设置为全局变量,但这种方式看起来更简洁。)


现在,脚本的名称空间包括名为
data
pdata
plt
的变量,这些变量具有所需的值。另外,您可以再次调用
main
,并将另一个文件传递给它,然后从该文件中获取值。

在这里回答我自己的问题。我知道这可能是一个评论,但我认为描述需要一个独立的答案

基本上,在花了一些时间来理解大家提到的关于我的变量超出范围的问题,以及处理这些问题的不同方法之后,我找到了另一个适合我的解决方案。我最终使用了IPython的embed()函数。对于调试过程,我要添加

...
from IPython import embed
embed()
...

在脚本中我想停下来四处看看的地方。一旦落入IPython壳中,我就可以研究可变尺寸,并进行操纵实验。当我找到我想要的组合时,我会复制命令,退出交互式解释器并修改脚本。这对我起作用的原因是它不涉及修改程序的结构来获取调试信息。

您的模块的名称空间中没有任何内容,只有
np
plt
pd
main
解析器
args
。特别是,
data
pdata
是已经完成的函数调用的局部变量。您的问题是因为您无法在不重新导入的情况下查看
pd
,还是缺少
args
?或者你看不到
数据
数据
?我想看
数据
数据
。所以我想我想要的是在退出
main()
之前让IPython“停止”?好吧,如果Python在执行
main
之前停止,那么这些值甚至还不会被创建。但是如果这是您想要的,那很简单:只需导入模块而不是运行它;然后你可以在空闲时调用
main
(并放入调试器断点或其他任何东西)。另一方面,如果你想
main
实际运行,但留下它的值,它必须要么使变量
global
,要么最好是
返回它们,让你的顶级脚本存储它们。这正是我想要的。令人惊讶的是,在IPython的命令行标志下,这个用例是不可能的。