资讯专栏INFORMATION COLUMN

交互式的开发环境 - ipython

Hydrogen / 3335人阅读

摘要:与操作系统交互在系统中执行将系统目录更改为调试器在执行完代码,如果出现错误,立即执行命令后将会进入调试器。性能分析用来测试各个部分或者函数的执行时间,它会自动多次执行以产生一个非常精确的平均执行时间。比的性能要快两倍以上。

本文介绍如何使用ipython进行快速的实验和调试,闲话免谈,直接通过demo进入主题。

与操作系统交互 !cmd

在系统shell中执行cmd

In [35]: !ls
Gemfile        Gemfile.lock    README.md    Rakefile    bin        config        db        log        src
%cd directory

将系统目录更改为directory

In [36]: %cd -
/private/tmp
调试器 %debug

在执行完代码,如果出现错误,立即执行%debug命令后将会进入调试器。在接触%debug之前,笔者都是使用的是pdb.set_trace来调试程序,这样的硬编码非常之不方便。

In [45]: !touch a.py
In [46]: !vim a.py
In [47]: !cat a.py
def divide():
    assert(1 == 0)

divide()
In [56]: %run a.py
---------------------------------------------------------------------------
AssertionError                      Traceback (most recent call last)
/private/tmp/a.py in ()
      2     assert(1 == 0)
      3
----> 4 divide()

/private/tmp/a.py in divide()
      1 def divide():
----> 2     assert(1 == 0)
      3
      4 divide()

AssertionError:

In [57]: %debug
> /private/tmp/a.py(2)divide()
      1 def divide():
----> 2     assert(1 == 0)
      3
      4 divide()
%run -d xxx.py

同样立即进入调试器。

性能分析 %timeit

用来测试各个部分或者函数的执行时间,它会自动多次执行以产生一个非常精确的平均执行时间。

In [12]: strings = ["foo", "foobar", "baz","qux", "123 ffd"] * 100000
In [13]: %timeit method1 = [x for x in strings if x.startswith("foo")]
10 loops, best of 3: 93.4 ms per loop
In [14]: %timeit method2 = [x for x in strings if x[:3] == "foo"]
10 loops, best of 3: 36.4 ms per loop

method2 比 method1 的性能要快两倍以上。

%run -p

python的主要性能分析工具是cProfile模块,它会记录各个函数的耗费时间,在命令行中,可以通过如下命令来进行性能分析:

python -m cProfile xxx.py

而在ipython中,会使用下面的命令来运行一个文件

%run -p -s cumulative xxx.py
%prun

如果想要运行一个函数或语句,请使用如下命令:

%prun -l 7 -s cumulative run()

待测函数:

In [17]: from numpy.random import randn
In [18]: x = randn(3000, 3000)
In [19]: y = randn(3000, 3000)
In [20]: def add_and_sum(x,y):
    ...:     added = x + y
    ...:     summed = added.sum(axis=1)
    ...:     return summed
    ...:

使用prun的结果如下:

In [21]: %prun add_and_sum(x, y)
         6 function calls in 0.340 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.310    0.310    0.335    0.335 :1(add_and_sum)
        1    0.025    0.025    0.025    0.025 {method "reduce" of "numpy.ufunc" objects}
        1    0.005    0.005    0.340    0.340 :1()
        1    0.000    0.000    0.025    0.025 {method "sum" of "numpy.ndarray" objects}
        1    0.000    0.000    0.025    0.025 _methods.py:31(_sum)
        1    0.000    0.000    0.000    0.000 {method "disable" of "_lsprof.Profiler" objects}

上面的结果不是很好理解,笔者更喜欢用line_profiler库来分析。

%lprun

使用一个库line_profiler,这个库的输出结果简单易理解。
这个库不是内建的,需要手动安装,安装命令:

pip install line_profiler

然后在ipython中手动load lprun:

In [2]: %load_ext line_profiler
In [3]: %lprun
Timer unit: 1e-06 s

待测函数:

In [17]: from numpy.random import randn
In [18]: x = randn(3000, 3000)
In [19]: y = randn(3000, 3000)
In [20]: def add_and_sum(x,y):
    ...:     added = x + y
    ...:     summed = added.sum(axis=1)
    ...:     return summed
    ...:
In [21]: def call_function():
    ...:     x = randn(1000, 1000)
    ...:     y = randn(1000, 1000)
    ...:     return add_and_sum(x, y)

使用lprun后的结果如下:

In [23]: %lprun -f add_and_sum  -f call_function call_function()
Timer unit: 1e-06 s

Total time: 0.004438 s
File: 
Function: add_and_sum at line 1

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     1                                           def add_and_sum(x,y):
     2         1         3929   3929.0     88.5      added = x + y
     3         1          508    508.0     11.4      summed = added.sum(axis=1)
     4         1            1      1.0      0.0      return summed

Total time: 0.062512 s
File: 
Function: call_function at line 1

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     1                                           def call_function():
     2         1        29193  29193.0     46.7      x = randn(1000, 1000)
     3         1        28449  28449.0     45.5      y = randn(1000, 1000)
     4         1         4870   4870.0      7.8      return add_and_sum(x, y)

通常,会使用%prun(cProfile)做“宏观”性能分析,而用%lprun(line_profiler)做“微观”性能分析。使用line_profiler必须要指定待测的函数,是因为这个库要跟踪每一行代码的执行时间。

基本名令 内省

在一个变量的前面或后面加上问号?,可以显示该变量的基本信息

In [23]: a=1

In [24]: a?
Type:        int
String form: 1
Docstring:
int(x=0) -> int or long
int(x, base=10) -> int or long
>>> int("0b100", base=0)
4

如果这个变量是函数的话,一个问号?来显示docstring,两个问号来显示该函数的源码

%timeit

检测python语句的执行时间

In [16]: %timeit  sum(i*i for i in xrange(1000))
10000 loops, best of 3: 68.6 µs per loop
%logstart

执行这个命令,开始记录控制台会话,这样可以将整个过程保存起来

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38561.html

相关文章

  • 工欲善其事必先利其器:用什么写Python?

    摘要:然而,每个人对编辑器的喜好各不相同,甚至引发出诸如神的编辑器与编辑器之神这种信仰之争。我们用来写的工具有两类一种是被称为的集成开发环境,它们为开发而生。但仅我上述提及的几个其实也足够用了。正如标题所说工欲善其事,必先利其器。 通常来说,每个程序员都有自己趁手的兵器: 代码编辑器 。你要是让他换个开发环境,恐怕开发效率至少下降三成。然而,每个人对编辑器的喜好各不相同,甚至引发出诸如神的编...

    Brenner 评论0 收藏0
  • JupyterLab:程序员笔记本神器

    摘要:对于有着完全的支持是一个交互式的开发环境,是的下一代产品,集成了更多的功能,等其正式版发布,相信那时就是被取代的时候通过使用,能够以灵活,集成和可扩展的方式处理文档和活动可以开启终端,用于交互式运行代码,完全支持丰富的输出支持,,,等任何文 showImg(https://segmentfault.com/img/remote/1460000018602436?w=1282&h=721...

    rubyshen 评论0 收藏0
  • 如何利用Python库Web3.py和Infura在Windows中设置托管以太坊节点

    摘要:第步启用与以太坊区块链交互从获得后。我希望本教程介绍了通过在操作系统中设置托管以太坊节点的基本步骤。这里是原文和中设置以太坊托管节点 如果你想与以太坊区块链进行交互以获取最新区块的详细信息,可以使用以太网节点、本地节点或托管节点连接到以太坊区块链的交易信息或发送交易。由于有许多第三方插件和应用程序可用于执行此操作,你可能会认为我们为什么需要一个节点。如果要部署智能合约或使用脚本自动与智...

    jaysun 评论0 收藏0
  • 如何利用Python库Web3.py和Infura在Windows中设置托管以太坊节点

    摘要:第步启用与以太坊区块链交互从获得后。我希望本教程介绍了通过在操作系统中设置托管以太坊节点的基本步骤。这里是原文和中设置以太坊托管节点 如果你想与以太坊区块链进行交互以获取最新区块的详细信息,可以使用以太网节点、本地节点或托管节点连接到以太坊区块链的交易信息或发送交易。由于有许多第三方插件和应用程序可用于执行此操作,你可能会认为我们为什么需要一个节点。如果要部署智能合约或使用脚本自动与智...

    AlphaGooo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<