如何让 Python 像 Julia 一样快地运行

Julia 与 Python 的比较

我是否应丢弃 Python 和其他语言,使用 Julia 执行技术计算?在看到 http://julialang.org/ 上的基准测试后,人们一定会这么想。Python
和其他高级语言在速度上远远有些落后。但是,我想到的第一个问题有所不同:Julia 团队能否以最适合 Python 的方式编写 Python 基准测试?

我对这种跨语言比较的观点是,应该根据要执行的任务来定义基准测试,然后由语言专家编写执行这些任务的最佳代码。如果代码全由一个语言团队编写,则存在其他语言未得到最佳使用的风险。

Julia 团队有一件事做得对,那就是他们将他们使用的代码发布到了 github 上。具体地讲,Python 代码可在此处找到。

第一眼看到该代码,就可以证实我所害怕的偏见。该代码是以 C 风格编写的,在数组和列表上大量使用了循环。这不是使用 Python 的最佳方式。

我不会责怪 Julia 团队,因为我很内疚自己也有同样的偏见。但我受到了残酷的教训:付出任何代价都要避免数组或列表上的循环,因为它们确实会拖慢 Python
中的速度,请参阅 Python 不是 C

考虑到对 C 风格的这种偏见,一个有趣的问题(至少对我而言)是,我们能否改进这些基准测试,更好地使用 Python 及其工具?

在我给出答案之前,我想说我绝不会试图贬低 Julia。在进一步开发和改进后,Julia 无疑是一种值得关注的语言。我只是想分析 Python
方面的事情。实际上,我正在以此为借口来探索各种可用于让代码更快运行的 Python 工具。

在下面的内容中,我使用 Docker 镜像在 Jupyter Notebook 中使用 Python 3.4.3,其中已安装了所有的 Python 科学工具组合。我还会通过
Windows 机器上的 Python 2.7.10,使用 Anaconda 来运行代码。计时是对 Python 3.4.3 执行的。包含下面的所有基准测试的完整代码的 Notebook 可在此处找到。

鉴于各种社交媒体上的评论,我添加了这样一句话:我没有在这里使用 Python 的替代性实现。我没有编写任何 C
代码:如果您不信,可试试寻找分号。本文中使用的所有工具都是 Anaconda 或其他发行版中提供的标准的 Cython 实现。下面的所有代码都在单个 Notebook中运行。

我尝试过使用来自 github 的 Julia 微性能文件,但不能使用 Julia 0.4.2 原封不动地运行它。我必须编辑它并将 @timeit 替换为
@time,它才能运行。在对它们计时之前,我还必须添加对计时函数的调用,否则编译时间也将包含在内。我使用的文件位于此处。我在用于运行 Python 的同一个机器上使用 Julia 命令行接口运行它。

计时代码

Julia 团队使用的第一项基准测试是 Fibonacci 函数的一段简单编码。

1
2
def fib(n):
if n

此函数的值随 n 的增加而快速增加,例如:

Python

1
fib(100) = 354224848179261915075

可以注意到,Python 任意精度 (arbitrary precision) 很方便。在 C 等语言中编写相同的函数需要花一些编码工作来避免整数溢出。在 Julia
中,需要使用 BigInt 类型。

所有 Julia 基准测试都与运行时间有关。这是 Julia 中使用和不使用 BigInt 的计时:

1
2
0.000080 seconds (149 allocations:10.167 KB)
0.012717 seconds (262.69 k allocations:4.342 MB)

在 Python Notebook 中获得运行时间的一种方式是使用神奇的 %timeit。例如,在一个新单元中键入:

1
%timeit fib(20)

执行它会获得输出:

1
100 loops, best of 3:3.33 ms per loop

这意味着计时器执行了以下操作:

  1. 运行 fib(20) 100 次,存储总运行时间
  2. 运行 fib(20) 100 次,存储总运行时间
  3. 运行 fib(20) 100 次,存储总运行时间
  4. 从 3 次运行中获取最小的运行时间,将它除以 100,然后输出结果,该结果就是 fib(20) 的最佳运行时间

这些循环的大小(100 次和 3 次)会由计时器自动调整。可能会根据被计时的代码的运行速度来更改循环大小。

Python 计时与使用了 BigInt 时的 Julia 计时相比出色得多:3 毫秒与 12 毫秒。在使用任意精度时,Python 的速度是 Julia 的 4
倍。

但是,Python 比 Julia 默认的 64 位整数要慢。我们看看如何在 Python 中强制使用 64 位整数。

使用 Cython 编译

一种编译方式是使用 Cython 编译器。这个编译器是使用 Python
编写的。它可以通过以下命令安装:

pip install Cython

如果使用 Anaconda,安装会有所不同。因为安装有点复杂,所以我编写了一篇相关的博客文章:将 Cython For Anaconda 安装在 Windows 上

安装后,我们使用神奇的 %load_ext 将 Cython 加载到 Notebook 中:

1
%load_ext Cython

然后就可以在我们的 Notebook 中编译代码。我们只需要将想要编译的代码放在一个单元中,包括所需的导入语句,使用神奇的 %%cython 启动该单元:

1
2
3
4
5
%%cython
 
 
def fib_cython(n):
if n

执行该单元会无缝地编译这段代码。我们为该函数使用一个稍微不同的名称,以反映出它是使用 Cython
编译的。当然,一般不需要这么做。我们可以将之前的函数替换为相同名称的已编译函数。

对它计时会得到:

1
1000 loops, best of 3:1.22 ms per loop

哇,几乎比最初的 Python 代码快 3 倍!我们现在比使用 BigInt 的 Julia 快 100 倍。

我们还可以尝试静态类型。使用关键字 cpdef 而不是 def 来声明该函数。它使我们能够使用相应的 C 类型来键入函数的参数。我们的代码变成了:

1
2
3
4
%%cython
 
cpdef long fib_cython_type(long n):
if n

执行该单元后,对它计时会得到:

1
10000 loops, best of 3:36 µs per loop

太棒了,我们现在只花费了 36 微秒,比最初的基准测试快约 100 倍!这与 Julia 所花的 80 毫秒相比更出色。

有人可能会说,静态类型违背了 Python
的用途。一般来讲,我比较同意这种说法,我们稍后将查看一种在不牺牲性能的情况下避免这种情形的方法。但我并不认为这是一个问题。Fibonacci
函数必须使用整数来调用。我们在静态类型中失去的是 Python 所提供的任意精度。对于 Fibonacci,使用 C 类型 long
会限制输入参数的大小,因为太大的参数会导致整数溢出。

请注意,Julia 计算也是使用 64 位整数执行的,因此将我们的静态类型版本与 Julia 的对比是公平的。

缓存计算

我们在保留 Python 任意精度的情况下能做得更好。fib 函数重复执行同一种计算许多次。例如,fib(20) 将调用 fib(19) 和
fib(18)。fib(19) 将调用 fib(18) 和 fib(17)。结果 fib(18) 被调用了两次。简单分析表明,fib(17) 将被调用 3
次,fib(16) 将被调用 5 次,等等。

在 Python 3 中,我们可以使用 functools 标准库来避免这些重复的计算。

1
2
3
4
from functools import lru_cache as cache
@cache(maxsize=None)
def fib_cache(n):
if n

对此函数计时会得到:

1
1000000 loops, best of 3:910 ns per loop

速度又增加了 40 倍,比最初的 Python 代码快约 3,600 倍!考虑到我们仅向递归函数添加了一条注释,此结果非常令人难忘。

Python 2.7 中没有提供这种自动缓存。我们需要显式地转换代码,才能避免这种情况下的重复计算。

1
2
def fib_seq(n):
if n

请注意,此代码使用了 Python 同时分配两个局部变量的能力。对它计时会得到:

1
1000000 loops, best of 3:1.77 µs per loop

我们又快了 20 倍!让我们在使用和不使用静态类型的情况下编译我们的函数。请注意,我们使用了 cdef 关键字来键入局部变量。

1
2
3
4
%%cython
 
def fib_seq_cython(n):
if n

我们可在一个单元中对两个版本计时:

1
2
3
%timeit fib_seq_cython(20)
 
%timeit fib_seq_cython_type(20)

结果为:

1
2
1000000 loops, best of 3:953 ns per loop
10000000 loops, best of 3:51.9 ns per loop

静态类型代码现在花费的时间为 51.9 纳秒,比最初的基准测试快约 60,000(六万)倍。

如果我们想计算任意输入的 Fibonacci 数,我们应坚持使用无类型版本,该版本的运行速度快 3,500 倍。还不错,对吧?

使用 Numba 编译

让我们使用另一个名为 Numba 的工具。它是针对部分 Python 版本的一个即时
(jit) 编译器。它不是对所有 Python 版本都适用,但在适用的情况下,它会带来奇迹。

安装它可能很麻烦。推荐使用像 Anaconda 这样的 Python 发行版或一个已安装了 Numba 的 Docker 镜像。完成安装后,我们导入它的 jit 编译器:

1
from numba import jit

它的使用非常简单。我们仅需要向想要编译的函数添加一点修饰。我们的代码变成了:

1
2
3
@jit
def fib_seq_numba(n):
if n

对它计时会得到:

1
1000000 loops, best of 3:225 ns per loop

比无类型的 Cython 代码更快,比最初的 Python 代码快约 16,000 倍!

使用 Numpy

我们现在来看看第二项基准测试。它是快速排序算法的实现。Julia 团队使用了以下 Python 代码:

1
2
3
4
5
6
def qsort_kernel(a, lo, hi):
i = lo
j = hi
while i  pivot:
j -= 1
if i

我将他们的基准测试代码包装在一个函数中:

1
2
3
4
import random
def benchmark_qsort():
lst = [ random.random() for i in range(1,5000) ]
qsort_kernel(lst, 0, len(lst)1)

对它计时会得到:

1
100 loops, best of 3:18.3 ms per loop

上述代码与 C 代码非常相似。Cython 应该能很好地处理它。除了使用 Cython 和静态类型之外,让我们使用 Numpy
数组代替列表。在数组大小较大时,比如数千个或更多元素,Numpy 数组确实比
Python 列表更快。

安装 Numpy 可能会花一些时间,推荐使用 Anaconda 或一个已安装了 Python 科学工具组合的 Docker 镜像

在使用 Cython 时,需要将 Numpy 导入到应用了 Cython 的单元中。在使用 C 类型时,还必须使用 cimport 将它作为 C 模块导入。Numpy
数组使用一种表示数组元素类型和数组维数(一维、二维等)的特殊语法来声明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
%%cython
 
import numpy as np
cimport numpy as np
cpdef np.ndarray[double, ndim=1]
qsort_kernel_cython_numpy_type(np.ndarray[double, ndim=1] a,
long lo,
long hi):
cdef:
long i, j
double pivot
i = lo
j = hi
while i  pivot:
j -= 1
if i

对 benchmark_qsort_numpy_cython() 函数计时会得到:

1
1000 loops, best of 3:1.32 ms per loop

我们比最初的基准测试快了约 15 倍,但这仍然不是使用 Python 的最佳方法。最佳方法是使用 Numpy 内置的 sort()
函数。它的默认行为是使用快速排序算法。对此代码计时:

1
2
3
def benchmark_sort_numpy():
lst = np.random.rand(5000)
np.sort(lst)

会得到:

1
1000 loops, best of 3:350 µs per loop

我们现在比最初的基准测试快 52 倍!Julia 在该基准测试上花费了 419 微秒,因此编译的 Python 快 20%。

我知道,一些读者会说我不会进行同类比较。我不同意。请记住,我们现在的任务是使用主机语言以最佳的方式排序输入数组。在这种情况下,最佳方法是使用一个内置的函数。

剖析代码

我们现在来看看第三个示例,计算 Mandelbrodt 集。Julia 团队使用了这段 Python 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def mandel(z):
maxiter = 80
c = z
for n in range(maxiter):
if abs(z) > 2:
return n
z = z*z + c
return maxiter
def mandelperf():
r1 = np.linspace(2.0, 0.5, 26)
r2 = np.linspace(1.0, 1.0, 21)
return [mandel(complex(r, i)) for r in r1 for i in r2]
 
assert sum(mandelperf()) == 14791

最后一行是一次合理性检查。对 mandelperf() 函数计时会得到:

1
100 loops, best of 3:4.62 ms per loop

使用 Cython 会得到:

1
100 loops, best of 3:1.94 ms per loop

还不错,但我们可以使用 Numba 做得更好。不幸的是,Numba 还不会编译列表推导式 (list
comprehension)。因此,我们不能将它应用到第二个函数,但我们可以将它应用到第一个函数。我们的代码类似以下代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
@jit
def mandel_numba(z):
maxiter = 80
c = z
for n in range(maxiter):
if abs(z) > 2:
return n
z = z*z + c
return maxiter
def mandelperf_numba():
r1 = np.linspace(2.0, 0.5, 26)
r2 = np.linspace(1.0, 1.0, 21)
return [mandel_numba(complex(r, i)) for r in r1 for i in r2]

对它计时会得到:

1
1000 loops, best of 3:503 µs per loop

还不错,比 Cython 快 4 倍,比最初的 Python 代码快 9 倍!

我们还能做得更好吗?要知道是否能做得更好,一种方式是剖析代码。内置的 %prun 剖析器在这里不够精确,我们必须使用一个称为 line_profiler 的更好的剖析器。它可以通过
pip 进行安装:

1
pip install line_profiler

安装后,我们需要加载它:

1
%load_ext line_profiler

然后使用一个神奇的命令剖析该函数:

1
%lprun s f mandelperf_numba mandelperf_numba()

它在一个弹出窗口中输出以下信息。

1
2
3
4
5
6
7
8
9
10
Timer unit:1e06 s
Total time:0.003666 s
File:
Function: mandelperf_numba at line 11
Line # Hits Time Per Hit % Time Line Contents
==============================================================
11 def mandelperf_numba():
12 1 1994 1994.0 54.4 r1 = np.linspace(2.0, 0.5, 26)
13 1 267 267.0 7.3 r2 = np.linspace(1.0, 1.0, 21)
14 1 1405 1405.0 38.3 return [mandel_numba(complex(r, i)) for r in r1 for i in r2]

我们看到,大部分时间都花费在了 mandelperf_numba() 函数的第一行和最后一行上。最后一行有点复杂,让我们将它分为两部分来再次剖析:

1
2
3
4
5
def mandelperf_numba():
r1 = np.linspace(2.0, 0.5, 26)
r2 = np.linspace(1.0, 1.0, 21)
c3 = [complex(r, i) for r in r1 for i in r2]
return [mandel_numba(c) for c in c3]

剖析器输出变成:

1
2
3
4
5
6
7
8
9
10
11
Timer unit:1e06 s
Total time:0.002002 s
File:
Function: mandelperf_numba at line 11
Line # Hits Time Per Hit % Time Line Contents
==============================================================
11 def mandelperf_numba():
12 1 678 678.0 33.9 r1 = np.linspace(2.0, 0.5, 26)
13 1 235 235.0 11.7 r2 = np.linspace(1.0, 1.0, 21)
14 1 617 617.0 30.8 c3 = [complex(r, i) for r in r1 for i in r2]
15 1 472 472.0 23.6 return [mandel_numba(c) for c in c3]

我们可以看到,对函数 mandel_numba() 的调用仅花费了总时间的 1/4。剩余时间花在 mandelperf_numba()
函数上。花时间优化它是值得的。

 

再次使用 Numpy

使用 Cython 在这里没有太大帮助,而且 Numba 不适用。摆脱此困境的一种方法是再次使用 Numpy。我们将以下代码替换为生成等效结果的 Numpy
代码。

1
return [mandel_numba(complex(r, i)) for r in r1 for i in r2]

此代码构建了所谓的二维网格。它计算由 r1 和 r2 提供坐标的点的复数表示。点 Pij 的坐标为 r1[i] 和 r2[j]。Pij 通过复数 r1[i] +
1j*r2[j] 进行表示,其中特殊常量 1j 表示单个虚数 i。

我们可以直接编写此计算的代码:

1
2
3
4
5
6
7
8
9
10
11
@jit
def mandelperf_numba_mesh():
width = 26
height = 21
r1 = np.linspace(2.0, 0.5, width)
r2 = np.linspace(1.0, 1.0, height)
mandel_set = np.zeros((width,height), dtype=int)
for i in range(width):
for j in range(height):
mandel_set[i,j] = mandel_numba(r1[i] + 1j*r2[j])
return mandel_set

请注意,我将返回值更改为了一个二维整数数组。如果要显示结果,该结果与我们需要的结果更接近。

对它计时会得到:

1
10000 loops, best of 3:140 µs per loop

我们比最初的 Python 代码快约 33 倍!Julia 在该基准测试上花费了 196 微秒,因此编译的 Python 快 40%。

向量化

让我们来看另一个示例。老实地讲,我不确定要度量什么,但这是 Julia 团队使用的代码。

1
2
3
4
5
6
7
8
def parse_int():
for i in range(1,1000):
n = random.randint(0,2**321)
s = hex(n)
if s[1]==‘L’:
s = s[0:1]
m = int(s,16)
assert m == n

实际上,Julia 团队的代码有一条额外的指令,用于在存在末尾的 ‘L’ 时删除它。我的 Anaconda 安装需要这一行,但我的 Python 3
安装不需要它,所以我删除了它。最初的代码是:

1
2
3
4
5
6
7
8
def parse_int():
for i in range(1,1000):
n = random.randint(0,2**321)
s = hex(n)
if s[1]==‘L’:
s = s[0:1]
m = int(s,16)
assert m == n

对修改后的代码计时会得到:

1
100 loops, best of 3:3.33 ms per loop

Numba 似乎没什么帮助。Cython 代码运行速度快了约 5 倍:

1
1000 loops, best of 3:617 µs per loop

Cython 代码运行速度快了约 5 倍,但这还不足以弥补与 Julia 的差距。

我对此基准测试感到迷惑不解,我剖析了最初的代码。以下是结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Timer unit:1e06 s
Total time:0.013807 s
File:
Function: parse_int at line 1
Line # Hits Time Per Hit % Time Line Contents
==============================================================
1 def parse_int():
2 1000 699 0.7 5.1 for i in range(1,1000):
3 999 9149 9.2 66.3 n = random.randint(0,2**321)
4 999 1024 1.0 7.4 s = hex(n)
5 999 863 0.9 6.3 if s[1]==‘L’:
6 s = s[0:1]
7 999 1334 1.3 9.7 m = int(s,16)
8 999 738 0.7 5.3 assert m == n

可以看到,大部分时间都花费在了生成随机数上。我不确定这是不是该基准测试的意图。

加速此测试的一种方式是使用 Numpy 将随机数生成移到循环之外。我们一次性创建一个随机数数组。

1
2
3
4
5
6
7
def parse_int_vec():
n = np.random.randint(0,2**321,1000)
for i in range(1,1000):
ni = n[i]
s = hex(ni)
m = int(s,16)
assert m == ni

对它计时会得到:

1
1000 loops, best of 3:848 µs per loop

还不错,快了 4 倍,接近于 Cython 代码的速度。

拥有数组后,通过循环它来一次向某个元素应用 hex() 和 int() 函数似乎很傻。好消息是,Numpy 提供了一种向数组应用函数的方法,而不必使用循环,该函数是
numpy.vectorize() 函数。此函数接受一次处理一个对象的函数。它返回一个处理数组的新函数。

1
2
3
4
5
6
7
8
vhex = np.vectorize(hex)
vint = np.vectorize(int)
def parse_int_numpy():
n = np.random.randint(0,2**321,1000)
s = vhex(n)
m = vint(s,16)
np.all(m == n)
return s

此代码运行速度更快了一点,几乎像 Cython 代码一样快:

1
1000 loops, best of 3:703 µs per loop

我肯定 Python 专家能够比我在这里做得更好,因为我不太熟悉 Python 解析,但这再一次表明避免 Python 循环是个不错的想法。

结束语

上面介绍了如何加快 Julia 团队所使用的 4 个示例的运行速度。还有 3 个例子:

  • pisum 使用 Numba 的运行速度快 29 倍。
  • randmatstat 使用 Numpy 可将速度提高 2 倍。
  • randmatmul 很简单,没有工具可应用到它之上。

包含所有 7 个示例的完整代码的 Notebook 可在此处获得。

我们在一个表格中总结一下我们的结果。我们给出了在最初的 Python 代码与优化的代码之间实现的加速。我们还给出了对 Julia
团队使用的每个基准测试示例使用的工具。

时间以微秒为单位 Julia Python
优化后的代码
Python 初始代码 Julia / Python 优化后的代码 Numpy Numba Cython
Fibonacci
64 位
80 36 不使用 2.2 X
Fib BigInt 12,717 1,220 3,330 10
快速排序 419 350 18,300 1.2 X
Mandelbrodt 196 140 4,620 1.4 X X
pisum 34,783 35,300 804,000 0.99 X
randmatmul 95,975 137,000 137,000 0.73
parse int 244 617 3,330 0.4 X X
randmatstat 14,544 117,000 230,000 0.12 X

这个表格表明,在前 4 个示例中,优化的 Python 代码比 Julia 更快,后 3 个示例更慢。请注意,为了公平起见,对于
Fibonacci,我使用了递归代码。

我认为这些小型的基准测试没有提供哪种语言最快的明确答案。举例而言,randmatstat 示例处理 5×5 矩阵。使用 Numpy
数组处理它有点小题大做。应该使用更大的矩阵执行基准测试。

我相信,应该在更复杂的代码上对语言执行基准测试。Python 与
Julia 比较–一个来自机器学习的示例
中提供了一个不错的示例。在该文章中,Julia 似乎优于 Cython。如果我有时间,我会使用 Numba
试一下。

无论如何,可以说,在这个小型基准测试上,使用正确的工具时,Python 的性能与 Julia 的性能不相上下。相反地,我们也可以说,Julia 的性能与编译后的
Python 不相上下。考虑到 Julia 不需要对代码进行任何注释或修改,所以这本身就很有趣。

补充说明

我们暂停一会儿。我们已经看到在 Python 代码性能至关重要时,应该使用许多工具:

  • 使用 line_profiler 执行剖析。
  • 编写更好的 Python 代码来避免不必要的计算。
  • 使用向量化的操作和通过 Numpy 来广播。
  • 使用 Cython 或 Numba 编译。

使用这些工具来了解它们在哪些地方很有用。与此同时,请谨慎使用这些工具。分析您的代码,以便可以将精力放在值得优化的地方。重写代码来让它变得更快,有时会让它难以理解或通用性降低。因此,仅在得到的加速物有所值时这么做。Donald
Knuth 曾经恰如其分地提出了这条建议:

“我们在 97% 的时间应该忘记较小的效率:不成熟的优化是万恶之源。”

但是请注意,Knuth 的引语并不意味着优化是不值得的,例如,请查看停止错误地引用 Donald Knuth 的话!‘不成熟的优化是恶魔’的谎言

Python 代码可以优化,而且应该在有意义的时间和位置进行优化。

我们最后给出一个讨论我所使用的工具和其他工具的有趣文章列表:

2015 年 12 月 16 日更新。Python 3.4 拥有一个能显著加速 Fibonacci() 函数的内置缓存。我更新了这篇文章来展示它的用途。

2015 年 12 月 17 日更新。在运行 Python 的相同机器上 运行 Julia 0.4.2 会导致时间增加。

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

两个命令把 Vim 打造成 Python IDE

先卸载:
gj@Dell ~ % sudo /home/gj/anaconda2/bin/pip uninstall vim-debug
The directory ‘/home/gj/.cache/pip/http’ or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo’s -H flag.
Uninstalling vim-debug-1.5.4:
/home/gj/anaconda2/bin/install-vim-debug.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug-1.5.4-py2.7.egg-info
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/__init__.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/__init__.pyc
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/_commands.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/_commands.pyc
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/commands.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/commands.pyc
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/dbgp.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/dbgp.pyc
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/debugger.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/debugger.pyc
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/errors.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/errors.pyc
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/new_debugger.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/new_debugger.pyc
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/protocol.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/protocol.pyc
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/stack.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/stack.pyc
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/subwindows.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/subwindows.pyc
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/ui.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/ui.pyc
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/window.py
/home/gj/anaconda2/lib/python2.7/site-packages/vim_debug/window.pyc
Proceed (y/n)? y
Successfully uninstalled vim-debug-1.5.4
The directory ‘/home/gj/.cache/pip/http’ or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo’s -H flag.

再重新安装:
gj@Dell ~ % sudo /home/gj/anaconda2/bin/pip install vim-debug
The directory ‘/home/gj/.cache/pip/http’ or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo’s -H flag.
The directory ‘/home/gj/.cache/pip’ or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo’s -H flag.
Collecting vim-debug
Downloading vim-debug-1.5.4.tar.gz
Installing collected packages: vim-debug
Running setup.py install for vim-debug
Successfully installed vim-debug-1.5.4

显示vim-debug信息:
gj@Dell ~ % pip show vim-debug

Metadata-Version: 1.0
Name: vim-debug
Version: 1.5.4
Summary: a plugin for vim that creates an integrated debugging environment
Home-page: http://jaredforsyth.com/projects/vim-debug/
Author: Jared Forsyth
Author-email: jared@jaredforsyth.com
License: UNKNOWN
Location: /home/gj/anaconda2/lib/python2.7/site-packages
Requires:

gj@Dell ~ % vi test.py
python module vim_debug not found…
Press ENTER or type command to continue

貌似还是不行。。。

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

网站访问来源热力图呈现的简单数据可视化

本文作者: 伯乐在线路易十四 。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者

个人博客运营了一年,收集到陆陆续续的访问者总数约12w个ip地址。突然手痒,想知道都是哪些地方来的访问者,就用百度api和一些python的简单处理,小半天完成了一简单数据可视化练手项目。

源代码在 github中: https://github.com/luyishisi/IP_location_wordpress

本文讲述从wordpress中记录访问者的ip,从数据库中取出后使用python调用百度api完成ip转换经纬信息。再通过热力图呈现出来。

0.目录

  • ip采集插件SlimStat
  • 数据库导出json
  • ip转化经纬
  • 百度IP定位api_字典解析
  • 生成输出json信息
  • 调用百度地图api呈现热力图

1.ip采集插件:SlimStat

想要实践本项目需要大量ip信息,则使用wordpress插件SlimStat进行ip信息采集.请在插件项目中安装并且使用上一天有一定数据后再继续项目

QQ截图20160626200744

QQ截图20160626185216

2.数据库导出json

此部分会sql语句的可以直接进入mysql导出,也可以使用phpmyadmin作为可视化导出

进入phpmyadmin后台,选择博客的的数据库

.QQ截图20160626201043

在这个表中,有所有访问的ip记录,进入后

修改上方的sql语句为:SELECT ip FROM  wp_slim_stats

执行之后页面就将只检索出ip的信息,然后下方有导出按钮,点击后选择自定义为json格式,导出得到:

QQ截图20160626201628

QQ截图20160626201525

保存为文件名  ip_add_all.json

3.ip转化经纬

4.百度IP定位api_字典解析

5.生成输出json信息

以下代码解决上面三个问题(不知道为什么代码没有显示出来,我用截图吧)

2016-08-29 18-02-55屏幕截图

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import urllib2
import time
IpList = open(“ip_add_all.json”,“r”).read()
Ip = eval(IpList)
flag = 0
file = open(‘point.json’,‘w’)
for i in range(20):#这里的数字要估算你的有多少数据
    ip = Ip[i][‘ip’]
    res = urllib2.urlopen(“http://api.map.baidu.com/location/ip?ak=KrmZxHHwvLnl4Xfyt0FMMVzgGLaaxU2j&ip=”+ip+“&coor=bd09ll”)
    #这部分里ak的值最好换成你的,如果零时用可以先用我的
    a = res.read()
    zidian = eval(a)
    flag += 1
    if(zidian[‘status’] == 0):
        print flag,ip
        lng =  zidian[‘content’][‘point’][‘x’]
        lat =  zidian[‘content’][‘point’][‘y’]
        #print lat,lng
        str_temp = ‘{“lat”: ‘+lat+‘, “lng”:’+lng+‘},n’
        file.write(str_temp)    
file.close()

这部分使用百度的api.如果想自己使用的话则需要申请一个帐号和应用,他会给你一个ak密钥,加入到下面的代码中就可以自动完成ip–>经纬了

http://lbsyun.baidu.com/apiconsole/key  这里可以找到百度api的信息,在开放平台里.

python的代码则很简单

转化之后得到的是:

QQ截图20160626203117

完成转化

 

调用百度地图api呈现热力图

经过前面两轮的操作,已经从数据库得到ip_json,并且,使用百度ip定位api将ip转化为经纬度坐标,也写成json文件,现在的代码则是需要调用百度地图api中的热力图呈现.

http://developer.baidu.com/map/jsdemo.htm#c1_15

这部分api可以在这里找到

观察发现:

修改里面的point数组,则可以将之前采集的点呈现上去,

好吧,这里开始偷工减料了,之需要将之前json复制到这个point里面,并且保持格式一致,则点击运行就可以直接看到项目的结果啦..

你可以下载下面我做的这个all.html文件,然后点击在浏览器运行,就可以看到效果,不过这时候还是需要你手动把自己的加入进去.

all

最终热力图的样子如下:

QQ截图20160626193304QQ截图20160626193253

原创文章,转载请注明: 转载自URl-team

打赏支持我写出更多好文章,谢谢!
打赏作者

打赏支持我写出更多好文章,谢谢!

2
5 收藏

1 评论





关于作者:路易十四


少年程序猿,从事数据采集挖掘方面:个人博客,www.urlteam.org,邮箱:a83533774@gmail.com主要技能树:python,爬虫,linux,web前端,ACM,骑行。


个人主页 ·
我的文章

· 7 ·   

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

scrapy入门教程2:建立一个简单的爬取南邮新闻标题的爬虫demo

0. 基本环境说明

  1. 本文截图及运行环境均在MAC OS X 10.9.5上实现,但基本步骤与win 7环境上相同(其实我是先在win7折腾了一把,然后为了写这篇教程,又在OS X 上面重新搞了一遍)
  2. scrapy版本为1.0
  3. 参考文献以及下载链接:

1. 建立步骤

通过上一篇内容我们已经将scrapy环境配置完毕,下面我们来实现一个demo来爬取南京邮电大学新闻页面的内容。

1. 创建一个新工程

1
scrapy startproject njupt #其中njupt是项目名称,可以按照个人喜好来定义


输入以上命令之后,就会看见命令行运行的目录下多了一个名为njupt的目录,目录的结构如下:

1
2
3
4
5
6
7
8
9
| njupt
| | njupt
|   | __init__.py
|   | items.py        #用来存储爬下来的数据结构(字典形式)
|    | pipelines.py    #用来对爬出来的item进行后续处理,如存入数据库等
|    | settings.py    #爬虫配置文件
|    | spiders        #此目录用来存放创建的新爬虫文件(爬虫主体)
|     | __init__.py
| | scrapy.cfg        #项目配置文件


至此,工程创建完毕。

2. 设置 items

本文以抓取南邮新闻为例,需要存储三种信息:

  1. 南邮新闻标题
  2. 南邮新闻时间
  3. 南邮新闻的详细链接

items内部代码如下:

1
2
3
4
5
6
7
8
9
# -*- coding: utf-8 -*-
 
import scrapy
 
 
class NjuptItem(scrapy.Item): #NjuptItem 为自动生成的类名
    news_title = scrapy.Field() #南邮新闻标题
    news_date = scrapy.Field()     #南邮新闻时间
    news_url = scrapy.Field()   #南邮新闻的详细链接

至于为什么每一句都用scrapy.Field(),这个等请关注我的后续教程,现在只要记住按照以上的格式来添加新的要提取的属性就可以了~。

3. 编写 spider

spider是爬虫的主体,负责处理requset response 以及url等内容,处理完之后交给pipelines进行进一步处理。
设置完items之后,就在spiders目录下新建一个njuptSpider.py文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# -*- coding: utf-8 -*-
import scrapy
from njupt.items import NjuptItem
import logging
class njuptSpider(scrapy.Spider):
    name = “njupt”
    allowed_domains = [“njupt.edu.cn”]
    start_urls = [
        “http://news.njupt.edu.cn/s/222/t/1100/p/1/c/6866/i/1/list.htm”,
        ]
    
    def parse(self, response):
        news_page_num = 14
        page_num = 386
        if response.status == 200:
            for i in range(2,page_num+1):
                for j in range(1,news_page_num+1):
                    item = NjuptItem()
                    item[‘news_url’],item[‘news_title’],item[‘news_date’] = response.xpath(
                    “//div[@id=’newslist’]/table[1]/tr[“+str(j)+“]//a/font/text()”
                    “|//div[@id=’newslist’]/table[1]/tr[“+str(j)+“]//td[@class=’postTime’]/text()”
                    “|//div[@id=’newslist’]/table[1]/tr[“+str(j)+“]//a/@href”).extract()
                  
                    yield item
                    
                next_page_url = “http://news.njupt.edu.cn/s/222/t/1100/p/1/c/6866/i/”+str(i)+“/list.htm”
                yield scrapy.Request(next_page_url,callback=self.parse_news)
        
    def parse_news(self, response):
        news_page_num = 14
        if response.status == 200:
            for j in range(1,news_page_num+1):
                item = NjuptItem()
                item[‘news_url’],item[‘news_title’],item[‘news_date’] = response.xpath(
                “//div[@id=’newslist’]/table[1]/tr[“+str(j)+“]//a/font/text()”
                “|//div[@id=’newslist’]/table[1]/tr[“+str(j)+“]//td[@class=’postTime’]/text()”
                “|//div[@id=’newslist’]/table[1]/tr[“+str(j)+“]//a/@href”).extract()
                yield item

其中

  1. name为爬虫名称,在后面启动爬虫的命令当中会用到。
  2. allowed_domains为允许爬虫爬取的域名范围(如果连接到范围以外的就不爬取)
  3. start_urls表明爬虫首次启动之后访问的第一个Url,其结果会被自动返回给parse函数。4.
  4. parse函数为scrapy框架中定义的置函数,用来处理请求start_urls之后返回的response,由我们实现
  5. news_page_num = 14page_num = 386别表示每页的新闻数目,和一共有多少页,本来也可以通过xpath爬取下来的,但是我实在是对我们学校的网站制作无语了,html各种混合,于是我就偷懒手动输入了。
  6. 之后通过item = NjuptItem()来使用我们之前定义的item,用来存储新闻的url、标题、日期。(这里面有一个小技巧就是通过|来接连xpath可以一次返回多个想要抓取的xpath)
  7. 通过yield item来将存储下来的item交由后续的pipelines处理
  8. 之后通过生成next_page_url来通过scrapy.Request抓取下一页的新闻信息
  9. scrapy.Request的两个参数,一个是请求的URL另外一个是回调函数用于处理这个requestresponse,这里我们的回调函数是parse_news
  10. parse_news里面的步骤和parse差不多,当然你也可以改造一下parse然后直接将其当做回调函数,这样的话一个函数就ok了

4. 编写 pipelines

初次编写可以直接编辑njupt目录下的pipelines.py文件。pipelines主要用于数据的进一步处理,比如类型转换、存储入数据库、写到本地等。
本爬虫pipelines如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
import json
 
class NjuptPipeline(object):
    def __init__(self):
        self.file = open(‘njupt.txt’,mode=‘wb’)
    def process_item(self, item, spider):
        self.file.write(item[‘news_title’].encode(“GBK”))
        self.file.write(“n”)
        self.file.write(item[‘news_date’].encode(“GBK”))
        self.file.write(“n”)
        self.file.write(item[‘news_url’].encode(“GBK”))
        self.file.write(“n”)
        return item

其实pipelines是在每次spideryield item 之后调用,用于处理每一个单独的item。上面代码就是实现了在本地新建一个njupt.txt文件用于存储爬取下来的内容。

5. 编写 settings.py

settings.py文件用于存储爬虫的配置,有很多种配置,由于是入门教程,不需要配置很多,我们这里就添加一下刚才编写的pipelines就行了。文件内容如下。

1
2
3
4
5
6
7
8
9
BOT_NAME = ‘njupt’
 
SPIDER_MODULES = [‘njupt.spiders’]
NEWSPIDER_MODULE = ‘njupt.spiders’
 
 
ITEM_PIPELINES = {
    ‘njupt.pipelines.NjuptPipeline’:1,
}

6. 启动爬虫与查看结果

以上步骤全部完成之后,我们就启动命令行,然后切换运行目录到njuptspider目录下,通过以下命令启动爬虫

1
scrapy crawl njupt

经过一段时间的风狂爬取,爬虫结束。会报一些统计信息

最后让我们来查看一下爬取成果

至此,大功告成~

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

将Sublime Text 3设置为Python全栈开发环境

本文由 伯乐在线Lane 翻译,艾凌风 校稿。未经许可,禁止转载!
英文出处:realpython.com。欢迎加入翻译组

为 Sublime Text 3 设置 Python 的全栈开发环境

Sublime Text 3 (ST3) 是一个轻量级的跨平台文字编辑器,尤以其轻快的速度,易用性和强大的社区支持而著称。它一经面世便被认为是一个杰出的编辑器,而它真正的强大之处在于你可以使用 Package Control 来增加它的功能以及可以进行各种自定义设置。

在本文章中,我们将会看到如何将 Sublime Text 打造成为 Python 的全栈开发环境(从前端到后端),如何通过自定义主题和插件来增强它的基本功能,并且还将会涉及到很多使 ST3 变得更加强大的常用的命令,特性以及快捷键。

本教程将假定你使用的是 Mac 电脑并且习惯于使用终端。如果你使用的是 Windows 或者 Linux 操作系统,本文涉及到的一些命令将有可能会有所不同,但是你应该仍然可以很容易地通过 Google 来获取到与本教程相关的解答。

在我们开始之前,让我们先讨论一下我所谓的”全栈”具体指的是什么。

在现在的 HTML5 以及移动设备开发中,Javascript 简直无处不在。是的,无处不在!仅仅使用 Python 基于某个框架比如 Django 或者 Flask 进行开发是不够的。如果你想从始至终真正的自己开发一个网站的话,你必须熟悉 Javascript(以及 Javascript 的一大堆的框架),REST API(含状态传输 API),响应式设计,当然还有 HTML 和 CSS,以及其他许多东西。现在让我们来面对一个问题:就像其他任何一个手艺人一样,为了成为一个最厉害的程序员,你的工具必须犀利,你的开发环境必须被打造成全栈开发——那就是我们马上将要开始的工作…

特性

让我们从 ST3 的一些默认特性开始着手吧…

  1. Split Layouts 允许你将你的许多文件放到很多分割开来的视窗中。如果你正在进行以测试为目的的开发(将 Python 代码放在一个视窗中,而测试脚本放在另一个视窗中)或者正在进行前端开发(将 HTML 代码放在一个视窗里,CSS/Javascript 代码放在另一个视窗里)的时候将会非常有用。 
  2. Vintage Mode 让你能够在 ST3 中使用 vi 模式。
  3. Chrome-like Tabs 让你在多个文件中切换变得更加方便。
  4. Automatic loading of the last session 帮你自动打开你上次关闭的时候编辑器中所有打开的文件。我总是一直开着 ST3,而且其中打开着一大堆项目——当我重启电脑以后, 它能够自动帮我打开所有的这些文件和文件夹。
  5. Code Snippets 允许你通过一两个简单的关键字就能写出一段常用的代码片(Snippets),从而增加你的生产效率。比如,你只需要打开一个文件,输入 “lorem” 然后敲击 tab 键,就会自动生成一段乱数假文(译者注: 一种用于测试文章或文字在不同字型、版型下看起来的效果等的文字)。又比如在 Python 代码中,你可以输入 “defs” 然后敲击 tab 键,你就能得到一段通用的函数定义。

同时,你还可以点击 Tools > New Snippet 来创建属于你自己的代码片。请参照这个 文档 来获取帮助,也可以在 这里 查看我个人用到的一些 snippets。

自定义 Sublime Text 3

在你下载完 ST3 以后…

在命令行中添加 subl 命令

就像 TextMate 的 mate 命令一样,Sublime Text 拥有一个叫做 subl 的命令行工具,可以用来通过终端打开一个文件或者一整个文件夹。

你需要建立一个指向 subl 二进制文件的符号链接来使 subl 命令有效:

Python

1
$ ln s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" ~/bin/subl


尝试使用以下命令来打开 Sublime 来确保链接生效了:

Python

1
$ subl

如果以上命令没有效果,你可能需要将 /bin 添加到你的环境变量中:

Python

1
$ echo "export PATH=~/bin:$PATH" >> ~/.profile

然后重新尝试第一步。

如果你仍然遇到问题,尝试查看 这篇 文章来获取帮助。 或者你可以看看如何在 WindowsLinux 中建立符号链接。

现在你就可以通过下述命令来打开文件或者文件夹了:

Python

1
2
3
4
5
6
7
8
# open the current directory
$ subl .
 
# open a directory called tests
$ subl ~/Documents/test
 
# open a file called text.txt
$ subl test.txt

如果路径中含有空格,你必须使用双引号将路径括起来:

Python

1
$ subl "~/Documents/test/my test file.txt"

想要查询所有可用的命令,请打开帮助文件:

Python

1
$ subl help

安装 Package Control

为了使用众多的 插件 来扩展 Sublime 的功能,你需要安装一个叫做 Package Control 的插件管理器——这个东西你必须要手动安装。但是一旦你安装好了以后,你就可以使用 Package Control 来安装,移除或者升级所有的 ST3 插件了。

  1. 点击 这里 从 Sublime Text 3 官方获取用于安装的代码。依次点击 View > Show Console 打开 ST3 的控制台。在控制台中粘贴刚才的代码,然后点击回车。最后重启 ST3。
  2. 现在你可以通过快捷键 cmd+shift+P 打开 Package Control 来安装其他的插件了。输入 install 然后你就能看见屏幕上出现了 Package Control: Install Package,点击回车然后搜索你想要的插件。
  3. 其他一些相关命令如下:
    • List Packages 显示所有已安装的插件
    • Remove Packages 移除一个指定的插件
    • Upgrade Package 更新一个指定的插件
    • Upgrade/Overwrite All Packages 更新所有已安装的插件

请查阅官方 文档 获取更多的命令。

创建自定义配置文件

你可以通过一个基于 JSON 的配置文件来充分的自定义 Sublime Text,这使得转移或者同步你的自定义文件到另一个系统变得非常容易。首先,我们需要新建我们自己的配置文件。我们最好是为不同的系统环境和编程语言各自创建一个配置文件。

依次点击 Sublime Text > Preferences > Settings – User 来创建一个配置文件。在该文件中添加一个空的 JSON 类然后就可以在其中写入你的配置内容了。如下所示:

Python

1
2
3
4
5
6
7
{
      // base settings
      "auto_complete": false,
      "sublimelinter": false,
      "tab_size": 2,
      "word_wrap": true
}

  1. 如果想为特定的编程语言新建配置文件的话,请点击 Sublime Text > Preferences > Settings – More > Syntax Specific – User。然后按照 LANGUAGE.sublime-settings 的格式保存该配置文件。例如想新建一个 Python 专用的配置文件,请将该文件保存为 Python.sublime-settings。
  2. 你完全可以按照你自己的喜好来进行各项配置;不过我强烈推荐以我的这份 配置文件 以及 Python 配置 作为基础,然后修改成你所需要的内容。
  3. 一个可选项: 你可以使用 Dropbox 来同步你的所有配置。你只需要将你的配置文件上传到 Dropbox 然后就可以将你的配置同步到你的任意一台设备上了。
  4. 你可以在 Sublime Text Unofficial Documentation 找到一些非常好的参考配置。

主题

ST3 为你提供了完全自定义化一个适合自己主题的能力。当然,你如果不是那么的挑剔的话,你可以通过 Package Control 从许许多多的由 Sublime 社区设计的 主题 中下载一个。 在下载之前你可以通过 ColorSublime 来预览这些主题。

广受欢迎的的 Soda Dark 和极简风格的 Flatland 是我个人最喜欢的两个主题。

在安装完了主题以后, 请务必更新你的配置文件. Sublime Text > Preferences > Settings – User:

Python

1
2
3
4
{
      "theme": "Flatland Dark.sublimetheme",
      "color_scheme": "Packages/Theme Flatland/Flatland Dark.tmTheme"
}

插件

除了那些主题以外,我还会使用以下这一些插件来提升我的工作效率。

SideBarEnhancements

SideBarEnhancements 扩展了侧边栏中菜单选项的数量,从而提升你的工作效率。诸如”New file” 和 “Duplicate” 这样的选项对于 ST3 来说实在是太重要了, 我甚至觉得 ST3 本来就应该提供这些功能。而且仅凭 “Delete” 这一个功能就让这个插件值得下载。这个功能将你会在你删除文件的时候把它放入回收站。虽然这个功能乍一看没什么用,但是当你没有使用这样的功能而彻底删除了一个文件的时候,除非你用了版本管理软件,否则你将很难恢复这个文件。

现在就下载吧!

Anaconda

Anaconda 是一个终极 Python 插件。它为 ST3 增添了多项 IDE 类似的功能,例如:

  • Autocompletion 自动完成,该选项默认开启,同时提供多种配置选项
  • Code linting 使用支持 pep8 标准的 PyLint 或者 PyFlakes。因为我个人使用的是另外的 linting 工具,所以我会在 Anaconda 的配置文件 Anaconda.sublime-settings 中将 linting 完全禁用。操作如下: Sublime > Preferences > Package Settings > Anaconda > Settings – User: {"anaconda_linting": false}
  • McCabe code complexity checker 让你可以在特定的文件中使用 McCabe complexity checker. 如果你对软件复杂度检查工具不太熟悉的话,请务必先浏览上边的链接。
  • Goto Definitions 能够在你的整个工程中查找并且显示任意一个变量,函数,或者类的定义。
  • Find Usage 能够快速的查找某个变量,函数或者类在某个特定文件中的什么地方被使用了。
  • Show Documentation: 能够显示一个函数或者类的说明性字符串(当然,是在定义了字符串的情况下)

你可以在这里,或者通过 ST3 的 Package Settings: Sublime Text > Preferences > Package Settings > Anaconda > README 来查看所有这些特性。

SublimeCodeIntel 是另外一个非常流行的插件,它的许多特性与 Anaconda 类似。我建议同时也试试它。

Djaneiro

Djaneiro 支持 Django 模版和关键字高亮以及许多实用的代码片(snippets)功能。其中的 snippets 绝对是省时神器。你可以通过很少几个关键字就能创建许多常见的 Django 代码块比如 templates,models,forms,以及 views。请查看官方文档获取 snippets 列表。

我个人非常喜欢的以下两个用于创建 template 的代码片:输入 var 就可以新建 {{ }},而输入 tag 就能新建 {% %}

requirementstxt

Requirementstxt 可以为你的 requirements.txt 文件提供自动补全,语法高亮以及版本管理功能。

SublimeLinter

SublimeLinter 是 ST3 的一个代码静态检查工具框架(linter)。这个插件本身来说并不包含任何的一个 linter,但是你可以通过在 Package Control 中输入 SublimeLinter-[linter_name] 的方式来安装一个 linter。你可以点击这里查看官方的 linter。同时你还可以在 Package Control 中查看到许多的第三方 linter。请点击这里查看安装说明。

对于 Python 的代码静态检查器,我建议使用 SublimeLinter-pyflakesSublimeLinter-pep8

与此同时,我也会使用 SublimeLinter-jshint, SublimeLinter-pyyaml, SublimeLinter-csslintSublimeLinter-html-tidy,以及 SublimeLinter-json

以上大多数的 linter 都需要先安装一些依赖库才能使用,所以在安装前请务必阅读他们的安装说明。

你可以通过修改用户自定义的 SublimeLinter.sublime-settings 文件来对你的每个 linter 个性化:Sublime Text > Preferences > Package Settings > SublimeLinter > Settings – User. 例如我通过以下代码来忽略 pep8 中的错误和警告:

Python

1
2
3
4
5
6
7
8
"pep8": {
    "@disable": false,
    "args": [],
    "excludes": [],
    "ignore": "E501,C0301,W0142,W0402,R0201,E1101,E1102,C0103,R0901,R0903,R0904,C1001,W0223,W0232,W0201,E1103,R0801,C0111",
    "maxlinelength": 100,
    "select": ""
},

GitGutter

GitGutter 让 ST3 能在左边栏的位置显示一个小图标,用以表示在最后一次提交以后,代码是否有追加,修改或者删除。

如果你想让该插件支持分布式的版本管理软件(Git,SVN,Bazaar 和 Mercurial)。请查看 Modific

FTPSync

FTPSync 能够将你的项目和远程文件进行同步。你只需要打开文件便可以下载更新(如果你的远端文件比本地更加新的话),而且如果你对本地文件做出了修改可以立即同步到远程服务器。这是非常棒的同步本地文件和远程文件的方法。你可以通过以下的方法来添加你的远程服务器:Sublime Text > Preferences > Package Settings > FTPSync > Setup FTPSync.

Sample settings:

Python

1
2
3
4
5
6
7
8
9
10
11
{
  'primary': {
    host: 'ftp.mywebsite.com',
    username: 'johnsmith',
    password: 'secretpassword',
    path: '/www/',
 
    upload_on_save: true,
    tls: true
  }
}

我个人喜欢把密码设为 null 因为我不想让我的密码出现在配置文件中。这样 FTPSync 会在我每次保存完文件后要求我输入密码。

AdvancedNewFile

AdvancedNewFile 可以让你在 ST3 中使用简单的几个快捷键便创建一个新的文件夹或者一个新的文件:

你只需要通过几个快捷键便可以打开 AdvancedNewFile 的输入框。然后输入路径和文件名。当你按下回车键后,文件便被创建了。除此之外,如果目标文件夹并不存在的话,该文件夹将会被自动建立。在默认情况下,你创建的文件的路径将会显示在状态栏中。

请查看 Github 上的这篇文档来获取更为详细的使用说明。特别建议请详细阅读TAB自动补全(Tab Completion)以及预定义别名(Predefined Aliases)部分。

我把“cmd+n”设置为了通过 AdvancedNewFile 创建新文件的快捷方式。该快捷键可以通过修改 Key Bindings – User file 来实现 Sublime Text > Preferences > Package Settings > AdvancedNewFile > Key Bindings – User:

Python

1
2
3
[
  { "keys": ["cmd+n"], "command": "advanced_new_file_new"}
]

你也可以更改默认打开的文件夹路径:Sublime Text > Preferences > Package Settings > AdvancedNewFile > Settings – User

Python

1
{"default_initial": "/Users/michaelherman/Documents/repos"}

这样我创建新文件的时候,/Users/michaelherman/Documents/repos将会自动被添加到路径最前方,因为99%的情况下我都会把我的脚本放在这个路径下。

Emmet

Emmet,以前叫做 Zen Coding,让你可以通过简单的缩写来创建 HTML 或者 CSS 的代码块。

例如,你只需要输入感叹号!,然后按下 tab 键,便可以在一个 HTML 文件中创建一段带有几个基本标签的 HTML5 文档类型的代码:

Python

1
2
3
4
5
6
7
8
9
10
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF8">
  <title>Document</title>
</head>
<body>
 
</body>
</html>

请查看官方文档或者速查手册获取更多信息。

Markdown Preview

Markdown Preview 可以用来预览和编译 markdown 文件。

你可以打开 Package Manager 然后输入 Markdown Preview 来查看可用的命令:

  • Markdown Preview: Python Mrakdown: 在浏览器中预览
  • Markdown Preview: Python Mrakdown: 导出 HTML 文件
  • Markdown Preview: Python Mrakdown: 拷贝到剪贴板
  • Markdown Preview: Github风格Markdown: 在浏览器中预览
  • Markdown Preview: Github风格Markdown: 导出 HTML 文件
  • Markdown Preview: Github风格Markdown: 拷贝到剪贴板
  • Markdown Preview: 打开Markdown速查手册

一旦你完成转换,你之后的所有保存都会立即反映到转换的文件中。

快捷键

  1. 跳转到任意内容 (“cmd+p”) 用来快速查找和打开文件。你仅仅只需要工程中文件的一部分路径或者文件名你就可以很容易的打开这个文件。这在一个大型的 Django 工程中显得非常方便。
  2. 跳转到指定行 (“ctrl+g”) 让你在当前文件中跳转到指定行数。
  3. 跳转到标志 (“cmd+r”) 可以列出当前文件中所有的函数或者类,让你更方便查找。你可以通过输入关键字来查找你所需要的函数或者类。
  4. 跳转到行首 (cmd+left-arrow-key)跳转到行尾 (cmd+right-arrow-key)
  5. 删除当前行(ctrl+shift+k)
  6. 多重编辑 是我迄今为止最喜欢的快捷键

    Python

    1
    2
    1.选定一个单词,点击 **cmd+d** 来选择同样的单词,再次点击 **cmd+d** 继续选择下一个单词…
    2.或者 **cmd+单击”** 来指定多个你想要同时修改的地方。

  7. 块编辑 (option+left-mouse-click) 用于选择一整块的内容。通常在整理 CSV 文件的时候用于删除空白内容。

如果想了解更多关于快捷键的内容,请看一下这篇文章。

自定义命令

你可以很容易地使用 Python 来编辑你自己的自定义命令和快捷键组合。目前我个人使用的有以下这些:

  1. 拷贝当前文件路径到剪贴板 – 链接
  2. 关闭除当前活动标签页以外的所有其他标签页 – 链接

通过文件选项打开你的 Package 文件夹(Sublime > Preferences > Browse Packages),然后打开 User 文件夹,接下来将上述的 Python 文件添加到 “/Sublime Text 3/Packages/User” 文件夹中。最后请在 Key Bindings – User file (Sublime Text > Preferences > Package Settings > AdvancedNewFile > Key Bindings – User) 文件中完成快捷键绑定。

Python

1
2
3
4
5
6
7
8
9
10
11
12
[
  // Copy file name
  {
    "keys": ["cmd+shift+c"],
    "command": "copy_path_to_clipboard"
  },
  // Close all other tabs
  {
    "keys": ["cmd+alt+w"],
    "command": "close_tabs"
  }
]

额外资源

  1. Community-maintained documentation
  2. Package Manager documentation
  3. Unofficial documentation reference
  4. Pimp my Editor – Presentation

总结

我希望你能够通过阅读这篇文章将一些上面提到一些插件整合到你的 ST3 中。同时希望你能够改造自己的配置文件来创建一些属于自己的自定义设定,以此来提升你的工作效率。如果你有任何的建议或者意见,请在下方的评论栏中留下你的评论。 最后,请到这个 repo 中查看 dotfiles 文件夹,其中包含了我上文中所提到的一些文件。

谢谢!

Derrick Kearney 编辑。非常感谢!

1
23 收藏

3 评论





关于作者:Lane


@Lane麟


个人主页 ·
我的文章

· 12 ·    

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

Python状况:为什么PyPy是Python的未来?

英文原文:The Python condition. Why PyPy is the future of Python 编译:oschina

Python 现在已经不仅仅是胶水脚本语言了。 不信?看看下面使用Python的成功案例:

要是你正在寻找快速介绍美丽的Python语言,我推荐 My-Favorite-Python-Things

高级语言是主流

目前高级语言可以写出简单具有灵活性的代码,所以在快速创建应用程序的时候是一个不错的选择,你不需要花时间来处理各种数据类型 (所有接口示例代码都是为了满足编译处理),可能有些人就会争论了,这个特性会产生有bug的代码,但是 Guido van Rossum说:“生产的代码谁会不经过测试呢”? 静态语言在编译时期就能处理一些错误,但这并不能检测出所有的错误。最后你还是得编写测试代码。 而有这个时间完全可以为动态语言写出测试代码。此外人们还不能设计一个堪称完美的类型系统,对此Jim Treavor写了一些总结

新技术允许我们为动态语言设计一个高效的运行环境 (JavaScript V8, LuaJIT, Racket, Common Lisp…), 这也可以和大型的框架竞争 (JVM, .NET, …)

所有这一切都使得高级语言越来越流行得在大型企业和日常生活中使用。

Python能延续传奇吗?

现在Python非常流行,同时它的地位也受到竞争者的挑战。Python有良好的生态系统,也有大型软件和社区支持,但它缺乏其竞争者的高效和先进的运行环境。

Python 作为胶水语言.

正如我在开头说的一个特点,Python很容易连接各种编译库,这是它作为胶水语言在20年前流行的重要原因。但是目前依然活跃的工具已经很老旧了,你必须花大量精力才能使用它们。

  • ctypes
  • c 扩展 是邪恶的. 它们绑定到Python的特定版本还不能被重复使用. 更糟糕的是, CPython2和CPython3的c 扩展 API不一样. 想想将库移植到Python3会是什么情况吧!
  • Cython – 这是被设计用来编写C扩展的. 但是我敢确定,使用C扩展是你最后想做的事. Cython 是一个需要编译的外部工具. 它最终的代码并没有动态行为,但是它的语法还需要学习. Cython不支持类型推断. 使用Cpython你不得不去编译. Cython也不是一个标准. 它不能作为解释代码来执行. _nuitka_的作者 Kay Hayen在Static Compilation – That is the point总结的非常好.
  • swigboost – 这些是非常容易的, 通常修改下C/C++ 代码就可以了, 或者写一些方案文件.

相比之下,有很多新的工具能在相同的性能下(甚至超出),更好的处理这些任务。

  • cffi – 一个能轻松处理你的c库的包。在接触硬件或者支持其他软件时你会经常做这样的事(像数据库客户端、驱动程序)。尝试下在python里使用它是多么简单吧。你不需要写任何的封装,类型化代码。而且还有 CPython 和 PyPy 的支持。
  • bitey
将Python作为你代码的核心 – 胶水语言另一面

胶水语言也有另一面。我们来想想底层高性能编程的过程。可能看起来会是下面几个过程:

  • 构思
  • 很多复杂的底层代码和组织机构代码。很可能是一堆晦涩的泛型代码(为了重用性)。
  • 编写胶水语言
  • 编译
  • 运行
  • 极可能会做很多的调试,然后回去修改,考虑到有这么多的底层代码。

感谢Python的简便性、脚本语言的本质和大量的工具,将他作为你代码的模板和核心。这就意味着你只需要写最少的底层代码,让Python做剩下的事:生成组织代码和你的底层代码需要的环境。

这与以往Lisp的理念一样,代码即数据,代码能够被其他正在执行的代码理解(代码可以作为数据被处理)。因而机器可以理解运行时正在执行的代码,并且去优化它,通过通常的方式就能得到全部的数据信息,而不用像C++那样使用模板。这是C++和其他流行的编程语言所没有的。最终我们有相对更底层的抽象级别,而运行时信息相对更丰富,使得编译器可以:

  • 为未知的硬件做特化 (编码时),包括支持的数据类型,以及可用的优化方法。
  • 自动调整(tuning) (例如为库提供的数据,如 ATLAS…)
  • 推送更多的信息给编译器,得到更好的推理。
  • 人们不用为数据类型烦恼(运行时环境就已经可以保证快速、正确使用数据类型)

于是整个流程就好像这样:

  • 想法
  • 一点Python代码(最棒的部分),用来构建整个架构。然后是一些底层的代码 ,同样很棒,因为这些代码没有恶心的模板和上下文代码。事实上,底层的代码也可以通过Python代码生成。
  • 运行
  • 调试,比起前面的步骤时间更短一些

就性能而言,这样的过程相比之前的方法有着更好的前景。

这些是已经用到这种方式的:PyPy, cffi, PyOpenCL, PyCUDA, numba, theano…

把Python当做一个高速语言

有很多方法能用Python写出高速的代码。最流行而且仍在广泛传播的方法是,用底层语言来写应用里最复杂的部分,然后使用,这对python来说无疑是很不幸的事。

所有Python里出色的高效的工具都需要许多复杂的c代码,这阻碍了其他的贡献者进来。现在我们想要写出高速而且美观的python代码。

有很多工具可以把python代码编译成机器代码,比如:Nuitka, Python2C, Shedskin, pythran。我认为它们都是失败的,当你使用它们的时候,就需要跟动态行为说再见了。他们只支持一部分的python语言,并且离完全支持还有很大距离。我甚至不认为以后他们能做到。另外他们也没有用那些使JIT(Just-In-Time 运行时编译执行)的解决方案变得出色的先进的技术和运行时信息。

多核编程

这方面,Armins Rigo的文章写的很棒,可以参考:Multicore Programming in PyPy and CPython

解释器的设计

为了让下一步的开发更简单,实现动态语言的最佳状态,Python需要一个合适的架构。当前CPython的架构过于简单,因而限制比较大,很难做到像JIT编译器那样的功能。下面是一些在增强CPython解释器性能上的失败的努力:

  • psyco (被PyPy代替)
  • Unladen swallow
  • 消除GIL的很多失败的尝试
  • 还有一些尝试修复CPython一些缺陷的尝试: Stackless和HotPy,但是Guido (Python之父,仁慈的独裁者) 的坚持使得这些项目没有被合并到Python中。(说明一下,HotPy还不是产品级的东西)。

CPython最大的问题是他的C API,这部分没有很好的设计。其他部分的实现多少都受此影响。

我们能做什么?

  1. 在粘结代码中推进新工具的使用 ( cffibitey)
  2. 在公共库中停止对CPython的底层属性(C API,C扩展)的依赖。作为替代,采用有如下功能的中间工具:
  • cffi – 简化对C库的应用
  • cython – 编写可移植的C扩展。我并不推荐它用于通常的编程,不过它确实在维护C扩展方面更好一些,也更简单。Cython已经有CPython和PyPy后端。
为何 PyPy 是趋势?

PyPy为优化和进一步的语言开发提供了更好的架构。对于大部分Python已有的问题,PyPy已经提供了解决方案:

PyPy已经支持多平台 (x86, 64_x86, ARM)

PyPy同时还包含了一个优秀的现代的架构,在 Jim Huang 的演讲 中做了介绍,演讲的要点是:

  • 解释性语言的框架
  • 用于研究和产品的组件组合 (不同的数据模型,垃圾回收 – 这些可以在具体的应用场景进行改变)
  • 构建在基于组件链的功能架构之上(翻译工具链)。每一个步骤都会延续/转换程序模型、引入特征、各种后端(JVM, JavaScript, LLVM, GCC IR等等)。来看一下翻译链的例子:python 代码 -> 字节码 -> 函数对象 -> 类型推断 -> 垃圾收集器 -> JIT
  • 包含大量在架构的不同层次开发的现代的优化技术 (这个任务可以简化)

相信让所有软件支持PyPy需要付出艰巨的努力 – 需要在现有的库上做很多工作。不过使用新的工具,编写支持PyPy和CPython的软件会比采用C扩展的方式更简单一些(在我们能做什么一节有介绍)。

CPython遗留问题

现在来说一下CPython依赖性代码的遗留问题 (源于它们紧密依赖 c 扩展)。 这些主要是科学相关的软件 (NumPy, SciPy 等等)。Python在PyPy成为产品级软件之前早就被用于科学计算(我认为实在2年之前),之后这些软件在工具、代码和社区方面都得到很多发展。这些软件一起构建了一个很棒的平台,通常被用来作为Matlab之类的软件的替换(有人甚至认为是更好的选择)。要实现这些,C扩展是目前唯一的解决方案。现在,这些软件的发展仍然与CPython紧密绑定,因为要让科学计算相关的软件全部支持PyPy,需要大量的工作。近似的方案是使用按需执行的JIT – 对特定的函数做修饰,然后动态的把它们编译成机器码并切换到使用c扩展。这个想法不需要重写所有的科学计算的平台,而速度同样快速。采用这种方式的典型项目是numba,这是由Continuum Analytics (这家公司主要发布基于python库的强壮的科学计算平台)赞助的。Numba采用这种方式是因为它的快速脚本需要与其他依赖CPython的科学计算代码兼容。numba值得学一下,SciPy会议的numba演讲 是一个很好的阐述。

不得不说Python的科学计算社区非常棒。他们非常关注于质量、易用性和推广他们的产品(为此组织了很多会议:SciPy大会,PyData等)。感谢他们让Python成为免费的科学分析平台的首选。这里还需要提一下Travis Oliphant,他在社区中付出了很多努力,让整个平台协调一致。关于这些可以看一下这篇博客文章:为何Python是你最终必须学习的编程语言

PyPy呢?

我希望PyPy当时并没有达到产品级可用。

后续

关于本文的后续在Reddit上有一个有趣的讨论。这是关于在商业上应用PyPy的优缺点的讨论。讨论者总结了如何使用基于高性能库的PyPy。最重要的是使用PyPy软件栈(原始Python、cffi,等等)可以让维护和优化很简单(例如:延迟计算)。至于缺点,上面提到了,主要与CPython的遗留问题有关。

1
收藏

评论





转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

每个程序员都应该学习使用Python或Ruby

如果你是个学生,你应该会C,C++和Java。还会一些VB,或C#/.NET。多少你还可能开发过一些Web网页,你知道一些HTML,CSS和JavaScript知识。总体上说,我们很难发现会有学生显露出掌握超出这几种语言范围外的语言的才能。这真让人遗憾,因为还有很多种编程语言,它们能让你成为一个更好的程序员。

在这篇文章里,我将会告诉你,为什么你一定要学习Python或Ruby语言。

  • C/C++/Java相比 — Python/Ruby能让你用少的多的多的代码写出相同的程序。有人计算过,Python或Ruby写出的程序的代码行数只相当于相对应的Java代码的行数的五分之一。如果没有绝对的必要,为什么要花这么多时间写出这么多的代码呢?而且有人说,一个优秀的程序员能维护的代码量最多是2万行。这不区分用的语言究竟是汇编,C还是Python/Ruby/PHP/Lisp。所以,如果你用Python/Ruby写,你一个人干的,不管是干什么,如果换用Java/C/C++,那都需要一个5人的小团队来干。
  • VB/PHP比较 — 跟PHP/VB相比,Python/Ruby的是一种从设计上讲比它们好的不知多少倍的语言。PHP和VB分别是在开发网站和桌面应用程序上非常流行的语言。它们流行的原因是非常的易学。不懂计算机的人也很容易的上手。如果你用这些语言开发过大型的项目,你就会发现这些语言的设计是如此的糟糕。是朋友,他就不会劝你使用PHP/VB。
  • Lisp/Scala/Haskell/Closure/Erlang相比 — Python/Ruby跟它们比起来显得相当的“主流”。确实,这些语言每种都有其很酷的特征,对于高级编程人员,了解这些语言能给他们对编程的思考带来实际的提升。但这些应该在你以后的职业生涯中才去决定学哪一两种。对于现在,Python/Ruby是在语言功能和实际运用之间平衡后的更好的选择。
  • Perl相比 — Python和Ruby都受恩于Perl,在这两种语言异军突起前,Perl是最好、最大的一种动态语言。但现在,Perl已是昨日黄花,越来越多的人转向Ruby/Python。我感觉Perl的面向对象机制有点做作,很不好用。通常认为,Perl一种比较难学的语言,因为它提供你了太多不同的方法去完成同一个任务,它的语法有点像密码,非常不直观 — 除非你对它掌握的非常好。总之,我感觉Perl是一种对于学生来说不是很合适的语言—除非你有特殊的理由去学它(例如,你有很多正则表达式要处理,这是Perl的闪光点)。
  • sh/sed/awk/bash相比 — 如果你使用Linux/Unix,你可能需要做一些shell编程,甚至会编写一些不小的程序。但是,对于这些语言,一旦程序达到一定的行数,事情就会开始变得让你痛苦不堪,你最好是用Python去做这些事情。当然,做这种事情,Perl是最好的选择,Python排第二。(Ruby对于系统shell脚本不是很合适)。

你可以在Google上搜一下“为什么X比Y好” — 其中把X换成Python或Ruby,把Y换成另外一种语言 — 你就会发现,有无数的文章来说明它们为什么这么好。

如果你有选择你的毕业设计使用的编程语言的自由,你应该选择Python或Ruby,它们能让你在开发项目的过程中节省一半的时间(除非你要开发的是移动应用,这样你必须要使用Java或Objective-C)。

下面是xkcd上的一幅漫画,告诉你掌握Python后你会变得多么的强大:

如何去学它们呢?很多很多的网站上都提供了学习Python和Ruby的教材和课程。下面的是我从中选出的一些:

有疑问吗?请在评论了写出来,我会尽量回答你们。

尾注:

1 :我的这篇文章可能会让很多Perl爱好者很郁闷,现在回味一下,我认识到对这种语言的要求过于苛刻了。因此,我把关于Perl的一节改写了一下。

Python和Ruby都受恩于Perl,在这两种语言出现之前,Perl是最大、最好的动态语言。但Perl现在太老了。它的面向对象性不完整。它很久没有升级更新了,它的市场份额正在丢失。对于一些新的、很火的事物(例如Web编程框架,Web API),它不如Python & Ruby 那样能跟上时代的步伐。基本上,Python/Ruby在兴起,Perl在衰退。

2 :本文中的所有语言的比较都是用来给印度计算机科学专业的学生选编程语言时做参考的。像“X比Y好”这样的句子准确的讲是毫无意义的,因为所有的语言都是经过时间的考验而存活下来的,有些语言会在某些领域比另外一种要强,这也是它们存活下来的原因。换句话说,总有一些情况下,PHP/Java/C/C++/Perl 看起来会比 Ruby/Python 等其它语言显的更适合。

译文:外刊IT评论  原文:reliscore

 

1
收藏

3 评论





转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

Pyston:Dropbox 正开发的开源 Python 解释器

本文由 伯乐在线atupal 翻译。未经许可,禁止转载!
英文出处:Dropbox。欢迎加入翻译组

大家好,我非常激动宣布 Pyston,这是一个正在由 Dropbox 开发的开源 Python 解释器。 这个项目的目标是产生一个高性能的 Python 解释器,使 Python 也能用于那些被如 C++ 这样的传统系统语言占据的领域。

在 Dropbox ,我们热爱 Python ,尝试用它来做一切可以做的事情。然而随着规模的的变大和要处理的问题越来越多,我们开始发现继续使用 Python 而要达到我们的性能目标有时候极其困难。有时用另外一门语言重写也起不了多大作用。我本人非常喜欢 Python , 每次当我们决定重写什么东西的时候我都很受伤,所以我想为它做一点什么。在静态编译上做了一些无用功后,我们到处查资料然后发现 JIT 技术在 Javascript 上非常成功,尤其 是 Chrome 的 V8 引擎大大地改善了 Javascript 的性能。我们希望通过同样的技术也能在 Python 上达到相同的性能提升。

Pyston 现在仍然处于初期阶段,还不能投入使用。但我们希望早点在它的生命周期之初就公布并开源出来,这样我们就能和 Python 和 JIT 社区来合作开发了。太多的细节在这篇博客写不下,但我们想说一下我们为什么需要一个新的 Python 实现,以及讲一点点 Pyston 是怎么工作的。

为什么选择实现一个新的 Python 解释器

早就已经有了一大堆使用 JIT 技术的 Python 实现:PyPy 使用它的 tracing JIT 来提高性能;Jython 和 IronPython 都是构建在广泛支持 JIT 的虚拟机上的。所以为什么我们认为还值得开始创造一个新的实现呢?

简单来说,是因为我们认为绝大多数有前景的技术都和现有的实现不兼容。比如,在 Javascript 界就因为强大的性能优势从 tracing JIT 切换到 method-at-a-time JIT 。对 Python 是否有同样的性能优势还有待商榷,但由于这两种途径从根本上都是和现有的实现不兼容的,所以答案只能是构建一个新的 method-at-a-time JIT。

另外一个区别是我们对传统的垃圾回收器有计划地使用来高效地支持拓展模块。同样,我们现在也无法知道这是否是一种更好的方法,但这个决定对一个很难在现有的实现下进行测试的 JIT 来说是必不可少的。

从零开始的坏处就是,创造一个新的语言的实现毋庸置疑是一个巨大的任务。幸运的是, 有助于这个过程的一些工具已经开始出现了。尤其是 Pyston 是构建在 LLVM 之上的,使得我们不需要自己处理细节就可以生成上层的高质量代码。尽管如此,一个新的 Python 实现还是一个巨大 的工程,所以 Pyson 将不会马上就能投入使用。

它是怎么工作的

从顶层看,Pyston 将解析好的 Python 代码转换成 LLVM 中间代码。然后中间代码就通过 LLVM 的优化然后传递给 LLVM 的 JIT 引擎,产生可执行的机器代码。LLVM 包含许多优化步骤和机制,使得它能产生非常快的代码。

然而问题是 LLVM 不能推出 Python 代码,因为动态语言不得不把所有底层的行为都隐藏在类型分派(Type Dispatch)后。为了解决这个问题,Pyston 采用类型推断:虽然证明一个变量将会是某个特别的类型通常是不可能,但是 Pyston 经常可以根据一些确定的事实来预测某个对象会是什么类型。一旦做出 了一个预测,Pyston 将在运行时检测这个预测,在预测所对应的快速分支和预测失败所对应的慢速分支之间进行选择。

Pyston 还包含许多其他的现代技术,比如为快速查找属性和快速调用方法而设计的隐藏类和内联缓存。你可以在 Github 页面上找到更多的技术细节,以及一篇单独讲述这些技术细节的博文

现状

Pyston 仍然处于初始阶段,只支持 Python 语言的一个最小子集。拿基准测试数据来说话是不怎么公平的,因为 1) Pyston 不支持足够大的基准测试,所以这不具备代表意义。2) Pyston 不支持所有运行时特性(包括一些可能带来减速的特性),所以这不是一个同类的比较。 在这两点注意事项下,Pyston 在性能上通常可以击败 CPython,但是仍然弱于 PyPy。

代码以 Apache 2.0 许可证发布在 Github 上,技术文档正在增加。还有大量的工作需要做, 我们正在扩张团队:如果你对这类事感兴趣,请联系我们

请继续关注项目的进展。你也可以在这里订阅我们的邮件列表。

1
收藏

评论





关于作者:atupal


新浪微博:@_atupal,网站:atupal.org


个人主页 ·
我的文章

· 11

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

Spring Boot基础教程3-配置文件详解:Properties和YAML-演道网

Spring Boot基础教程1-Spring Tool Suite工具的安装

Spring Boot基础教程2-RESTfull API简单项目的快速搭建

Spring Boot基础教程3-配置文件详解:Properties和YAML

Spring Boot基础教程4-配置文件-多环境配置

Spring Boot基础教程5-日志配置-logback和log4j2


视频教程:http://www.roncoo.com/course/view/c99516ea604d4053908c1768d6deee3d

源码地址:https://github.com/roncoo/spring-boot-demo

一.配置文件的生效顺序,会对值进行覆盖:

1. @TestPropertySource 注解

2. 命令行参数

3. Java系统属性(System.getProperties())

4. 操作系统环境变量

5. 只有在random.*里包含的属性会产生一个RandomValuePropertySource

6. 在打包的jar外的应用程序配置文件(application.properties,包含YAML和profile变量)

7. 在打包的jar内的应用程序配置文件(application.properties,包含YAML和profile变量)

8. 在@Configuration类上的@PropertySource注解

9. 默认属性(使用SpringApplication.setDefaultProperties指定)


二.配置随机值

roncoo.secret=${random.value}

roncoo.number=${random.int}

roncoo.bignumber=${random.long}

roncoo.number.less.than.ten=${random.int(10)}

roncoo.number.in.range=${random.int[1024,65536]}

读取使用注解:@Value(value = “${roncoo.secret}”)

注:出现黄点提示,是要提示配置元数据,可以不配置


三.属性占位符

当application.properties里的值被使用时,它们会被存在的Environment过滤,所以你能够引用先前定义的值(比如,系统属性)。

roncoo.name=www.roncoo.com

roncoo.desc=${roncoo.name} is a domain name


四.Application属性文件,按优先级排序,位置高的将覆盖位置低的

1. 当前目录下的一个/config子目录

2. 当前目录

3. 一个classpath下的/config包

4. classpath根路径(root)

 

这个列表是按优先级排序的(列表中位置高的将覆盖位置低的

 

五. 配置应用端口和其他配置的介绍

   #端口配置:

server.port=8090

#时间格式化

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

#时区设置

spring.jackson.time-zone=Asia/Chongqing

 

六. 使用YAML代替Properties

    注意写法:冒号后要加个空格


项目源码地址

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

Windows Python Extension Packages

备注:

1.先要安装wheel库:pip install wheel

2.下载wheel,切换至下载路径,然后安装:pip install wheel库名.whl

 

Windows Python Extension Packages

by Christoph Gohlke, Laboratory for Fluorescence Dynamics, University of California, Irvine.



Other useful packages and applications not currently available on this page

  • AIDA implements the Adaptive Image Deconvolution Algorithm.
  • Alglib, a cross-platform numerical analysis and data processing library.
  • Babel, tools for internationalizing Python applications.
  • BALLView, a molecular modeling and visualization application.
  • Bioformats read and write life sciences file formats using Bio-Formats.
    Requires javabridge.
  • Biogeme performs estimation of discrete choice models.
  • BioImageXD is software for analysis and visualization of multidimensional biomedical images.
  • BisQue (Bio-Image Semantic Query User Environment), store, visualize, organize and analyze images in the cloud.
  • Blaze translates NumPy/Pandas-like syntax to systems like databases.
  • Bokeh, an implementation of the Grammar of Graphics for output to the HTML5 Canvas.
    Requires many dependencies.
  • CasADi implements automatic differentiation in forward and adjoint modes.
  • Certifi provides Mozilla’s CA Bundle.
  • CGAL-Python, bindings for the Computational Geometry Algorithms Library.
  • Coloc_utils computes colocalization coefficients from confocal images.
  • Cryptography exposes cryptographic primitives and recipes.
  • CVXPY, a modeling language for convex optimization problems.
    Requires numpy+mkl, scipy, cvxopt, scs, and ecos.
  • DeVIDE, a dataflow application builder for the rapid prototyping of medical visualization and image processing techniques.
  • Django, a high-level Web framework.
  • Docutils processes plaintext documentation into HTML, LaTeX, man-pages, open-document or XML.
  • Dpmix, a library for fitting massive mixture models.
  • EMAN2, a greyscale scientific image processing suite with a focus on transmission electron microscopy. Supports many image formats.
  • Epydoc, a tool for generating module API documentation.
  • FARSIGHT, a toolkit for microscopy image analysis based using Bio-Formats.
  • FiPy, a finite volume PDE solver.
    Requires pysparse.
  • Flask, a microframework based on Werkzeug, Jinja2 and good intentions.
  • Gexiv2, a GObject-based wrapper around the exiv2 library for image metadata.
  • GHMM, the General Hidden Markov Model library.
  • Graph-tool, an efficient module for manipulation and statistical analysis of graphs.
  • Ilastik, an interactive learning and segmentation toolkit.
  • IPython, an interactive computing environment.
    IPython 4 requires Jupyter.
    Some functions require setuptools, pyzmq, tornado, pygments, markupsafe, jinja2, mistune, rpy2, pycairo, matplotlib, pyqt4 or pyside, pandoc, and whatnot.
  • Iris, a library for analysing and visualising meteorological and oceanographic data sets
    Requires scipy, netcdf4-python, cartopy, shapely, udunits2 and other dependencies.
  • ITK (Insight Segmentation and Registration Toolkit), a software system for image analysis.
  • Jupyter, an interactive computing environment.
    Some functions require setuptools, ipython4, pyzmq, tornado, pygments, markupsafe, jinja2, mistune, rpy2, pycairo, matplotlib, pyqt4 or pyside, pandoc, and whatnot.
  • Lmfit, a least-squares minimization with constraints.
  • M2Crypto, a complete wrapper for OpenSSL.
  • Mako, a fast templating language.
  • Mantid, a framework that supports high-performance computing and visualization of scientific data.
  • MathGL, a library for scientific data visualization.
  • MDP, the Modular toolkit for Data Processing.
  • mMass, an mass spectrometry tool.
  • MMCorePy allows to control microscope hardware via Micro-Manager.
  • Msim, superresolution fluorescence microscopy of multicellular organisms.
  • Ncrypt is yet another OpenSSL wrapper.
  • NetworkX, a package for complex networks.
  • NiBabel, access a cacophony of neuro-imaging file formats.
  • Nipype, workflows and interfaces for neuroimaging packages.
  • NLTK, the Natural Language Toolkit.
    Requires pyyaml.
  • Nodebox-GL, a library for generating 2D animations.
  • Nose extends unittest to make testing easier.
  • Numeric is deprecated, superseded by Numpy.
  • OpenGLContext, a testing and learning environment for PyOpenGL.
  • OpenKinect provides access to the Xbox Kinect device.
    Requires LibUSB 1.2.6.
  • OpenMDAO, a Multidisciplinary Design Analysis and Optimization (MDAO) framework.
  • OpenSlide reads whole-slide images, high resolution images exceeding RAM sizes.
  • Panda3D, a framework for 3D rendering and game development.
  • ParticleStats performs analysis of intracellular particle motility and cytoskeletal polarity.
  • Patsy, a package for describing statistical models and for building design matrices.
  • Peak_detection implements the Gaussian peak detection described in Segré et al.
  • Pims, Python Image Sequence, loads video and sequential images.
  • Pip is the recommended tool for installing Python packages.
    Pip and setuptools are included with Python >=3.4 and >=2.7.9.
    To bootstrap pip on installations without pip, use the get-pip.py script or run
    python.exe pip-7.1.2-py2.py3-none-any.whl/pip install pip-7.1.2-py2.py3-none-any.whl.
  • Pmw, a toolkit for building high-level compound widgets using the Tkinter module.
  • PolyVox, a library for the storage and processing of volumetric environments.
  • Priithon, a platform for image analysis and algorithm development.
    Includes HIS, SDT, SIF, and SPE file readers.
  • PsychoPy, software for psychology and neuroscience.
  • Py-bcrypt, a wrapper of OpenBSD’s Blowfish password hashing code.
  • PyAudiere, a high-level audio interface using the Audiere sound library.
  • pyCGNS provides an interface to the CGNS/SIDS data model.
  • Pycparser, a complete parser for the C language.
  • PyCrypto provides cryptographic modules.
  • PyDSTool, a dynamical systems modeling, simulation and analysis environment.
  • Pyffmpeg, a wrapper for FFmpeg, a solution to record, convert and stream audio and video.
  • PyFFTW3 are bindings to the FFTW C library.
  • Pyglet, a cross-platform windowing and multimedia library using AVbin.
  • Pygments, a generic syntax highlighter.
  • PyGreSQL interfaces to a PostgreSQL database.
  • Pygrib, a module for reading GRIB meteorological files.
  • PyGSL provides an interface for the GNU Scientific Library (gsl).
  • PyGst, bindings for the GStreamer multimedia framework.
  • Pykit, a backend compiler for high-level typed code.
  • PyME, the Python Microscopy Environment, provides image acquisition and data analysis functionality for widefield microscopy applications.
  • Pymex embeds Python in a MATLAB(tm) 2011b extension module.
  • pyNFFT, a wrapper around the NFFT library.
  • PyNIfTI provides access to NIfTI and ANALYZE files.
  • Pyo, a digital signal processing module.
  • PyODE, a set of bindings for the Open Dynamics Engine.
  • pyOpenSSL, an interface to the OpenSSL library.
  • Pyparsing creates and executes simple grammars.
  • PyQt5, a set of bindings for the Qt5 application framework.
  • PyReadline (unstable, deprecated), a ctypes-based readline for Windows.
  • Pysam, a module for reading and manipulating SAM nucleotide sequence alignment files.
  • PySerial encapsulates the access for the serial port.
  • Pysifreader reads Andor SIF multi-channel image files.
  • PySUNDIALS provides bindings for the SUNDIALS suite of solvers.
  • PySVN interfaces the Subversion version control system.
  • Python-Dateutil extends the standard datetime module.
    Requires six.
  • Python-Ogre, an interface to the Ogre 3D graphics library.
  • Pythonisosurfaces, a marching cubes iso-surface implementation.
  • PythonOCC, a 3D CAD/CAE/PLM development framework.
  • PythonQwt, Qt plotting widgets.
    Requires pyqt4.
  • Pytools, a collection of tools.
    Requires six, decorator and appdirs.
  • Pytz provides world timezone definitions, modern and historical.
  • PyVISA, bindings to the “Virtual Instrument Software Architecture” VISA library.
  • Requests, a HTTP library for human beings.
  • RootPy provides an interface with the ROOT data analysis framework on top of PyROOT.
  • Scikit-bio (unstable) provides data structures, algorithms, and educational resources for bioinformatics.
  • Scikit-tracker, objects detection and robust tracking for cell biology.
  • SciTools are useful tools for scientific computing.
  • SCons, a software construction tool.
  • Setuptools downloads, builds, installs, upgrades, and uninstalls Python packages.
  • Sherpa, a modeling and fitting application.
  • Simpleaudio, simple audio playback.
  • SimpleCV, a framework for building computer vision applications.
  • Six, a Python 2 and 3 compatibility library.
  • SMC.FreeImage, a wrapper for the FreeImage library.
  • SpacePy tools for the space science community.
  • Spyder, the Scientific PYthon Development EnviRonment.
    Requires guiqwt and other dependencies.
  • Stdic computes a deformation function between images (image registration).
  • STScI_python provides a general astronomical data analysis infrastructure.
  • Sympy, a library for symbolic mathematics.
  • Trackpy, tools for particle tracking.
  • Trfit fits time-resolved fluorescence decays.
  • VIPS, an image processing library with no image size limits.
  • Virtualenv, a virtual Python environment builder.
  • VisionEgg produces stimuli for vision research experiments.
  • Vispy, OpenGL-based interactive visualization.
  • Visvis, a library for visualization of 1D to 4D data in an object oriented way.
  • ViTables, a GUI for browsing and editing files in PyTables and HDF5 formats.
  • WFastCGI provides a gateway between IIS’s FastCGI support to Python’s WSGI protocol.
  • Xmlsec, bindings for the XML Security Library.
  • Xray, N-D labeled arrays and datasets.
  • ZODB, the Zope Object Database, provides an object-oriented database.

Build Environment

  1. Libraries (built from source):
  2. Alembic
  3. AMD
  4. ANGLE
  5. ANN
  6. ASIO
  7. Aspell
  8. Assimp
  9. AVbin
  10. BerkeleyDB
  11. BLAS
  12. Blosc
  13. Boost
  14. Box2D
  15. bsd-xdr
  16. bzip2
  17. C-ares
  18. Cairo
  19. Cassowary
  20. CFitsIO
  21. CGAL
  22. Chipmunk2D
  23. EasyBMP
  24. Eigen
  25. Expat
  26. FFTW
  27. FLAC
  28. FLANN
  29. FLTK
  30. FMILibrary
  31. Freeglut
  32. FreeImage
  33. FreeTDS
  34. FreeType
  35. FreeXL
  36. GDAL
  37. GEOS
  38. GeoTIFF
  39. GLEW
  40. GLFW
  41. GLPK
  42. GLUT
  43. GraphicsMagick
  44. Graphviz
  45. GSL
  46. HDF4
  47. HDF5
  48. iconv
  49. ICU
  50. igraph
  51. ImageMagick
  52. ITK
  53. JasPer
  54. jsoncpp
  55. Jxrlib
  56. Kerberos
  57. KissFFT
  58. Klib
  59. LAME
  60. LAPACK
  61. LEMON
  62. lib3ds
  63. libcurl
  64. libevent
  65. Libffi
  66. libGD
  67. libgit2
  68. Libidn
  69. libInChI
  70. libjpeg
  71. libjpeg-turbo
  72. LIBLINEAR
  73. liblzma
  74. libmng
  75. libpng
  76. LibRaw
  77. libsamplerate
  78. libSBML
  79. libsodium
  80. libspatialindex
  81. LIBSVM
  82. LibTIFF
  83. libusb
  84. Libxml2
  85. Libxslt
  86. LibYAML
  87. Little CMS
  88. LLVM
  89. lp_solve
  90. lz4
  91. LZMA
  92. LZO
  93. Mesa
  94. METIS
  95. Minizip
  96. MPC
  97. MPEG_Encode
  98. MPFR
  99. MPIR
  100. MUMPS
  101. Muparser
  102. MySQL Connector/C
  103. NetCDF
  104. Netpbm
  105. ODE
  106. Ogg
  107. OpenAL
  108. OpenBabel
  109. OpenColorIO
  110. OpenCV
  111. OpenEXR
  112. OpenImageIO
  113. OpenJPEG
  114. OpenLDAP
  115. OpenMPI
  116. OpenNI
  117. OpenPGM
  118. OpenSSL
  119. PDCurses
  120. Pixman
  121. PortAudio
  122. PortMidi
  123. PostgreSQL
  124. PROJ.4
  125. Ptex
  126. Pthreads-w32
  127. Qhull
  128. Qt
  129. QuickFIX
  130. RE2
  131. RtMidi
  132. SASL
  133. SDL
  134. SDL_gfx
  135. SDL_image
  136. SDL_mixer
  137. SDL_ttf
  138. SFML2
  139. Silo
  140. SLICOT
  141. Smpeg
  142. Snappy
  143. sparsehash
  144. SPHEREPACK
  145. SQLite
  146. SuiteSparse
  147. SUNDIALS
  148. SuperLU
  149. SZip
  150. TCL/TK
  151. UDUNITS
  152. UMFPACK
  153. ViennaCL
  154. Vorbis
  155. VTK
  156. WebP
  157. wxWidgets
  158. Xerces
  159. Xmlsec
  160. YAML
  161. ZeroMQ
  162. zlib
  1. SDKs and libraries (prebuilt):
  2. Apache HTTP Server
  3. ASIO SDK
  4. Bio-Formats
  5. ESRI File Geodatabase API
  6. GTK2
  7. Intel Integrated Performance Primitives
  8. Intel Math Kernel Library
  9. Intel SDK for OpenCL Applications
  10. Intel Threading Building Blocks
  11. libsndfile
  12. MATLAB(tm)
  13. Microsoft DirectX SDK (June 2010)
  14. Microsoft MPI v6
  15. Microsoft Platform SDK for Windows Server 2003 R2
  16. Microsoft SQL Server
  17. Microsoft Windows SDK v6.1 Windows Server 2008 and .NET Framework 3.5
  18. Microsoft Windows SDK v7.0 for Windows 7 and .NET Framework 3.5 Service Pack 1
  19. Microsoft Windows SDK v7.1 for Windows 7 and .NET Framework 4
  20. NVidia CG Toolkit
  21. NVidia CUDA Toolkit
  22. Oracle Instant Client
  23. Oracle Java SE Development Kit
  24. Python
  25. R
  1. Compilers:
  2. Clang
  3. Intel Composer XE 2013 SP1
  4. Intel Parallel Studio XE 2016 Composer
  5. Lazarus
  6. Microsoft Platform SDK for Windows Server 2003 R2
  7. Microsoft Visual C++ 2008 Feature Pack
  8. Microsoft Visual C++ Compiler for Python 2.7
  9. Microsoft Visual Studio .NET 2003
  10. Microsoft Visual Studio 2008 Pro
  11. Microsoft Visual Studio 2010 Pro
  12. Microsoft Visual Studio 2015 Community
  13. MinGW
  14. MinGW-w64
  15. Mingw-w64-for-python
  16. NASM
  17. Rtools
  18. Yasm
  1. Build tools:
  2. ActivePerl
  3. Ant
  4. Bazaar
  5. Bento
  6. BJam
  7. CMake
  8. CVS
  9. Cygwin
  10. Cython
  11. doxygen
  12. Epydoc
  13. Git
  14. JCC
  15. Jom
  16. M4
  17. Mercurial
  18. MSYS
  19. MSYS2
  20. Node.js
  21. Nose
  22. NSIS
  23. PyPy
  24. Python
  25. SCons
  26. SIP
  27. Sphinx
  28. Subversion
  29. SWIG
  30. Waf
  1. Other software:
  2. 7-Zip
  3. Avconv
  4. com0com
  5. Dependency Walker
  6. FFmpeg
  7. GhostScript
  8. GnuWin32
  9. Info-ZIP
  10. Inkscape
  11. InpOutx64
  12. MEncoder
  13. MiKTeX
  14. Notepad++
  15. Pandoc
  16. PTVS
  17. Redis
  18. Spyder
  19. Sysinternals Suite
  20. Ubuntu
  21. Windows 10
  22. WingIDE
  23. WinMerge
  1. Other CPython distributions:
  2. ActivePython
  3. Anaconda
  4. Python(x,y)
  5. Pyzo
  6. WinPython

Christoph Gohlke, Laboratory for Fluorescence Dynamics

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn