python 魔法命令_1.2.2 魔法(Magic)命令(2)

1.2.2    魔法(Magic)命令(2)

图1 9显示了排序的耗时结果。横坐标为对数坐标轴,表示数组的长度;纵坐标为平均每个元素所需的排序时间。可以看出每个元素所需的平均排序时间与数组长度的对数成正比,因此可以计算出排序函数sorted()的时间复杂度为:O(nlogn)。

%%prun命令调用profile模块,对单元中的代码进行性能剖析。下面的性能剖析显示fib()运行了21891次,而fib_fast()则只运行了20次:

%%prun

def fib(n):

if n<2:

return 1

else:

return fib(n-1) + fib(n-2)

def fib_fast(n,a=1,b=1):

ifn== 1:

return b

else:

return fib_fast(n-1, b, a+b)

fib(20)

fib_fast(20)

21913 function calls (4 primitive calls) in 0.007 seconds

Ordered by: internal time

ncalls  tottime  percall  cumtime  percall filename:lineno(function)

21891/1    0.007    0.000    0.007    0.007:2(fib)

20/1    0.000    0.000    0.000    0.000:8(fib_fast)

1    0.000    0.000    0.007    0.007:2()

1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler'

objects}

3. 代码调试

%debug命令用于调试代码,它有两种用法:一种是在执行代码之前设置断点进行调试;另一种则是在代码抛出异常之后,执行%debug命令查看调用堆栈。下面先演示第二种用法:

import math

def sinc(x):

return math.sin(x) / x

[sinc(x) for x in range(5)]

---------------------------------------------------------------------------

ZeroDivisionError                         Traceback (most recent call last)

in()

4     return math.sin(x) / x

5

---->6 [sinc(x) for x in range(5)]

in sinc(x)

2

3 def sinc(x):

---->4     return math.sin(x) / x

5

6 [sinc(x) for x in range(5)]

ZeroDivisionError: float division by zero

上面的程序抛出了ZeroDivisionError异常,下面用%debug查看调用堆栈。在调试模式下可以使用pdb模块提供的调试命令,例如用命令p x显示变量x的值:

%debug

>(4)sinc()

3 def sinc(x):

---->4     return math.sin(x) / x

5

ipdb>p x

0

ipdb>q

还可以先设置断点,然后运行程序。但是%debug的断点需要指定文件名和行号,使用起来并不是太方便。本书提供了%%func_debug单元命令,可以通过它指定中断运行的函数。在下面的例子中,程序将在numpy.unique()的***行中断运行,然后通过输入命令n单步运行程序,***输入命令c继续运行:

%%func_debug np.unique

np.unique([1, 2, 5, 4, 2])

Breakpoint 1 at c:\winpython-32bit-2.7.9.2\python-2.7.9\lib\site-packages\numpy\lib\arraysetops.py:96

NOTE: Enter 'c' at the ipdb>prompt to continue execution.

>c:\winpython-32bit-2.7.9.2\python-2.7.9\lib\site-packages\numpy\lib\arraysetops.py(173)

unique()

172     """

-->173ar=np.asanyarray(ar).flatten()

174

ipdb>n

>c:\winpython-32bit-2.7.9.2\python-2.7.9\lib\site-packages\numpy\lib\arraysetops.py(175)

unique()

174

-->175optional_indices=return_indexor return_inverse

176optional_returns=optional_indicesor return_counts

ipdb>c

4. 自定义的魔法命令

scpy2.utils.nbmagics:该模块中定义了本书提供的魔法命令,如果读者使用本书提供的批处理运行Notebook,则该模块已经载入。notebooks\01-intro\scpy2-magics.ipynb是这些魔法命令的使用说明。

IPython提供了很方便的自定义魔法命令的方法。最简单的方法就是使用register_line_magic和register_cell_magic装饰器将函数转换为魔法命令。下面的例子使用register_line_magic定义了一个行魔法命令%find,它在指定的对象中搜索与目标匹配的属性名:

from IPython.core.magic import register_line_magic

@register_line_magic

def find(line):

from IPython.core.getipython import get_ipython

from fnmatch import fnmatch

items=line.split() 

patterns,target=items[:-1], items[-1]

ipython=get_ipython() 

names=dir(ipython.ev(target)) 

results= []

for pattern in patterns:

for name in names:

if fnmatch(name, pattern):

results.append(name)

return results

当调用%find行魔法命令时,魔法命令后面的所有内容都传递给line参数。 按照空格对line进行分隔,除***一个元素之外,其余的元素都作为搜索模板,而***一个参数则为搜索的目标。 通过get_ipython()函数获得表示IPython运算核的对象,通过该对象可以操作运算核。 调用运算核的ev()方法对表达式target求值以得到实际的对象,并用dir()获取该对象的所有属性名。

***使用fnmatch模块对搜索模板和属性名进行匹配,将匹配结果保存到results并返回。下面使用%find命令在numpy模块中搜索所有以array开头或包含mul的属性名:

import numpy as np

names= %find array* *mul* np

names

['array',                'array2string',         'array_equal',          'array_equiv',

'array_repr',           'array_split',          'array_str',            'multiply',

'polymul',              'ravel_multi_index']

喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码

51CTO读书频道活动讨论群:342347198

【责任编辑:book TEL:(010)68476606】

点赞 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值