Coder Social home page Coder Social logo

python's People

Contributors

fuhao715 avatar

Watchers

 avatar  avatar

python's Issues

Python 代码性能优化技巧

来源:张颖@developerworks
代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构、优化、扩展以及文档相关的事情通常需要消耗 80% 的工作量。优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率。

改进算法,选择合适的数据结构

一个良好的算法能够对性能起到关键作用,因此性能改进的首要点是对算法的改进。在算法的时间复杂度排序上依次是:

O(1) -> O(lg n) -> O(n lg n) -> O(n^2) -> O(n^3) -> O(n^k) -> O(k^n) -> O(n!)

因此如果能够在时间复杂度上对算法进行一定的改进,对性能的提高不言而喻。但对具体算法的改进不属于本文讨论的范围,读者可以自行参考这方面资料。下面的内容将集中讨论数据结构的选择。

字典 (dictionary) 与列表 (list)

Python 字典中使用了 hash table,因此查找操作的复杂度为 O(1),而 list 实际是个数组,在 list 中,查找需要遍历整个 list,其复杂度为 O(n),因此对成员的查找访问等操作字典要比 list 更快。

清单 1. 代码 dict.py

from time import time
 t = time()
 list = ['a','b','is','python','jason','hello','hill','with','phone','test',
 'dfdf','apple','pddf','ind','basic','none','baecr','var','bana','dd','wrd']
 #list = dict.fromkeys(list,True)
 print list
 filter = []
 for i in range (1000000):
 for find in ['is','hat','new','list','old','.']:
 if find not in list:
 filter.append(find)
 print "total run time:"
 print time()-t

上述代码运行大概需要 16.09seconds。如果去掉行 #list = dict.fromkeys(list,True) 的注释,将 list 转换为字典之后再运行,时间大约为 8.375 seconds,效率大概提高了一半。因此在需要多数据成员进行频繁的查找或者访问的时候,使用 dict 而不是 list 是一个较好的选择。

集合 (set) 与列表 (list)

set 的 union, intersection,difference 操作要比 list 的迭代要快。因此如果涉及到求 list 交集,并集或者差的问题可以转换为 set 来操作。

清单 2. 求 list 的交集:

from time import time
 t = time()
 lista=[1,2,3,4,5,6,7,8,9,13,34,53,42,44]
 listb=[2,4,6,9,23]
 intersection=[]
 for i in range (1000000):
 for a in lista:
 for b in listb:
 if a == b:
 intersection.append(a)
print "total run time:"
 print time()-t

上述程序的运行时间大概为:

total run time:

38.4070000648
清单 3. 使用 set 求交集

from time import time
 t = time()
 lista=[1,2,3,4,5,6,7,8,9,13,34,53,42,44]
 listb=[2,4,6,9,23]
 intersection=[]
 for i in range (1000000):
 list(set(lista)&set(listb))
 print "total run time:"
 print time()-t

改为 set 后程序的运行时间缩减为 8.75,提高了 4 倍多,运行时间大大缩短。读者可以自行使用表 1 其他的操作进行测试。

表 1. set 常见用法

语法 操作 说明

set(list1) | set(list2) union 包含 list1 和 list2 所有数据的新集合

set(list1) & set(list2) intersection 包含 list1 和 list2 **同元素的新集合

set(list1) – set(list2) difference 在 list1 中出现但不在 list2 中出现的元素的集合

对循环的优化

对循环的优化所遵循的原则是尽量减少循环过程中的计算量,有多重循环的尽量将内层的计算提到上一层。 下面通过实例来对比循环优化后所带来的性能的提高。程序清单 4 中,如果不进行循环优化,其大概的运行时间约为 132.375。

清单 4. 为进行循环优化前

from time import time
 t = time()
 lista = [1,2,3,4,5,6,7,8,9,10]
 listb =[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,0.01]
 for i in range (1000000):
 for a in range(len(lista)):
 for b in range(len(listb)):
 x=lista[a]+listb[b]
 print "total run time:"
 print time()-t

现在进行如下优化,将长度计算提到循环外,range 用 xrange 代替,同时将第三层的计算 lista[a] 提到循环的第二层。

清单 5. 循环优化后

from time import time
 t = time()
 lista = [1,2,3,4,5,6,7,8,9,10]
 listb =[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,0.01]
 len1=len(lista)
 len2=len(listb)
 for i in xrange (1000000):
 for a in xrange(len1):
 temp=lista[a]
 for b in xrange(len2):
 x=temp+listb[b]
 print "total run time:"
 print time()-t

上述优化后的程序其运行时间缩短为 102.171999931。在清单 4 中 lista[a] 被计算的次数为 1000000_10_10,而在优化后的代码中被计算的次数为 1000000*10,计算次数大幅度缩短,因此性能有所提升。

充分利用 Lazy if-evaluation 的特性

python 中条件表达式是 lazy evaluation 的,也就是说如果存在条件表达式 if x and y,在 x 为 false 的情况下 y 表达式的值将不再计算。因此可以利用该特性在一定程度上提高程序效率。

清单 6. 利用 Lazy if-evaluation 的特性

from time import time
 t = time()
 abbreviations = ['cf.', 'e.g.', 'ex.', 'etc.', 'fig.', 'i.e.', 'Mr.', 'vs.']
 for i in range (1000000):
 for w in ('Mr.', 'Hat', 'is', 'chasing', 'the', 'black', 'cat', '.'):
 if w in abbreviations:
 #if w[-1] == '.' and w in abbreviations:
 pass
 print "total run time:"
 print time()-t

在未进行优化之前程序的运行时间大概为 8.84,如果使用注释行代替第一个 if,运行的时间大概为 6.17。

字符串的优化

python 中的字符串对象是不可改变的,因此对任何字符串的操作如拼接,修改等都将产生一个新的字符串对象,而不是基于原字符串,因此这种持续的 copy 会在一定程度上影响 python 的性能。对字符串的优化也是改善性能的一个重要的方面,特别是在处理文本较多的情况下。字符串的优化主要集中在以下几个方面:

1、在字符串连接的使用尽量使用 join() 而不是 +:在代码清单 7 中使用 + 进行字符串连接大概需要 0.125 s,而使用 join 缩短为 0.016s。因此在字符的操作上 join 比 + 要快,因此要尽量使用 join 而不是 +。

清单 7. 使用 join 而不是 + 连接字符串

from time import time
t = time()
 s = ""
 list = ['a','b','b','d','e','f','g','h','i','j','k','l','m','n']
 for i in range (10000):
 for substr in list:
 s+= substr
 print "total run time:"
 print time()-t

同时要避免:

s = ""
 for x in list:
 s += func(x)

而是要使用:

slist = [func(elt) for elt in somelist]
 s = "".join(slist)

2、当对字符串可以使用正则表达式或者内置函数来处理的时候,选择内置函数。如 str.isalpha(),str.isdigit(),str.startswith((‘x’, ‘yz’)),str.endswith((‘x’, ‘yz’))

3、对字符进行格式化比直接串联读取要快,因此要使用

out = "%s%s%s%s" % (head, prologue, query, tail)

而避免

out = "" + head + prologue + query + tail + ""

使用列表解析(list comprehension)和生成器表达式(generator expression)

列表解析要比在循环中重新构建一个新的 list 更为高效,因此我们可以利用这一特性来提高运行的效率。

from time import time
 t = time()
 list = ['a','b','is','python','jason','hello','hill','with','phone','test',
 'dfdf','apple','pddf','ind','basic','none','baecr','var','bana','dd','wrd']
 total=[]
 for i in range (1000000):
 for w in list:
 total.append(w)
 print "total run time:"
 print time()-t

使用列表解析:

for i in range (1000000):
 a = [w for w in list]

上述代码直接运行大概需要 17s,而改为使用列表解析后 ,运行时间缩短为 9.29s。将近提高了一半。生成器表达式则是在 2.4 中引入的新内容,语法和列表解析类似,但是在大数据量处理时,生成器表达式的优势较为明显,它并不创建一个列表,只是返回一个生成器,因此效率较高。在上述例子上中代码 a = [w for w in list] 修改为 a = (w for w in list),运行时间进一步减少,缩短约为 2.98s。

其他优化技巧

1、如果需要交换两个变量的值使用 a,b=b,a 而不是借助中间变量 t=a;a=b;b=t;

>>> from timeit import Timer
 >>> Timer("t=a;a=b;b=t","a=1;b=2").timeit()
 0.25154118749729365
 >>> Timer("a,b=b,a","a=1;b=2").timeit()
 0.17156677734181258
 >>
>

2、在循环的时候使用 xrange 而不是 range;使用 xrange 可以节省大量的系统内存,因为 xrange() 在序列中每次调用只产生一个整数元素。而 range() 將直接返回完整的元素列表,用于循环时会有不必要的开销。在 python3 中 xrange 不再存在,里面 range 提供一个可以遍历任意长度的范围的 iterator。

3、使用局部变量,避免”global” 关键字。python 访问局部变量会比全局变量要快得多,因 此可以利用这一特性提升性能。

4、if done is not None 比语句 if done != None 更快,读者可以自行验证;

5、在耗时较多的循环中,可以把函数的调用改为内联的方式;

6、使用级联比较 “x < y < z” 而不是 “x < y and y < z”;

7、while 1 要比 while True 更快(当然后者的可读性更好);

8、build in 函数通常较快,add(a,b) 要优于 a+b。

定位程序性能瓶颈

对代码优化的前提是需要了解性能瓶颈在什么地方,程序运行的主要时间是消耗在哪里,对于比较复杂的代码可以借助一些工具来定位,python 内置了丰富的性能分析工具,如 profile,cProfile 与 hotshot 等。其中 Profiler 是 python 自带的一组程序,能够描述程序运行时候的性能,并提供各种统计帮助用户定位程序的性能瓶颈。Python 标准模块提供三种 profilers:cProfile,profile 以及 hotshot。

profile 的使用非常简单,只需要在使用之前进行 import 即可。具体实例如下:

清单 8. 使用 profile 进行性能分析

import profile
def profileTest():
   Total =1;
   for i in range(10):
       Total=Total*(i+1)
       print Total
   return Total
if __name__ == "__main__":
   profile.run("profileTest()")

程序的运行结果如下:
Alt Text
图 1. 性能分析结果

Python 代码性能优化技巧

其中输出每列的具体解释如下:

●ncalls:表示函数调用的次数;

●tottime:表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间;

●percall:(第一个 percall)等于 tottime/ncalls;

●cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间;

●percall:(第二个 percall)即函数运行一次的平均时间,等于 cumtime/ncalls;

●filename:lineno(function):每个函数调用的具体信息;

如果需要将输出以日志的形式保存,只需要在调用的时候加入另外一个参数。如 profile.run(“profileTest()”,”testprof”)。

对于 profile 的剖析数据,如果以二进制文件的时候保存结果的时候,可以通过 pstats 模块进行文本报表分析,它支持多种形式的报表输出,是文本界面下一个较为实用的工具。使用非常简单

import pstats
p = pstats.Stats('testprof')
p.sort_stats("name").print_stats()

其中 sort_stats() 方法能够对剖分数据进行排序, 可以接受多个排序字段,如 sort_stats(‘name’, ‘file’) 将首先按照函数名称进行排序,然后再按照文件名进行排序。常见的排序字段有 calls( 被调用的次数 ),time(函数内部运行时间),cumulative(运行的总时间)等。此外 pstats 也提供了命令行交互工具,执行 python – m pstats 后可以通过 help 了解更多使用方式。

对于大型应用程序,如果能够将性能分析的结果以图形的方式呈现,将会非常实用和直观,常见的可视化工具有 Gprof2Dot,visualpytune,KCacheGrind 等,读者可以自行查阅相关官网,本文不做详细讨论。

Python 性能优化工具

Python 性能优化除了改进算法,选用合适的数据结构之外,还有几种关键的技术,比如将关键 python 代码部分重写成 C 扩展模块,或者选用在性能上更为优化的解释器等,这些在本文中统称为优化工具。python 有很多自带的优化工具,如 Psyco,Pypy,Cython,Pyrex 等,这些优化工具各有千秋,本节选择几种进行介绍。

  • Psyco

psyco 是一个 just-in-time 的编译器,它能够在不改变源代码的情况下提高一定的性能,Psyco 将操作编译成有点优化的机器码,其操作分成三个不同的级别,有”运行时”、”编译时”和”虚拟时”变量。并根据需要提高和降低变量的级别。运行时变量只是常规 Python 解释器处理的原始字节码和对象结构。一旦 Psyco 将操作编译成机器码,那么编译时变量就会在机器寄存器和可直接访问的内存位置中表示。同时 python 能高速缓存已编译的机器码以备今后重用,这样能节省一点时间。但 Psyco 也有其缺点,其本身运行所占内存较大。目前 psyco 已经不在 python2.7 中支持,而且不再提供维护和更新了,对其感兴趣的可以参考 http://psyco.sourceforge.net/

  • Pypy

PyPy 表示 “用 Python 实现的 Python”,但实际上它是使用一个称为 RPython 的 Python 子集实现的,能够将 Python 代码转成 C, .NET, Java 等语言和平台的代码。PyPy 集成了一种即时 (JIT) 编译器。和许多编译器,解释器不同,它不关心 Python 代码的词法分析和语法树。 因为它是用 Python 语言写的,所以它直接利用 Python 语言的 Code Object.。 Code Object 是 Python 字节码的表示,也就是说, PyPy 直接分析 Python 代码所对应的字节码 ,,这些字节码即不是以字符形式也不是以某种二进制格式保存在文件中, 而在 Python 运行环境中。目前版本是 1.8. 支持不同的平台安装,windows 上安装 Pypy 需要先下载https://bitbucket.org/pypy/pypy/downloads/pypy-1.8-win32.zip,然后解压到相关的目录,并将解压后的路径添加到环境变量 path 中即可。在命令行运行 pypy,如果出现如下错误:”没有找到 MSVCR100.dll, 因此这个应用程序未能启动,重新安装应用程序可能会修复此问题”,则还需要在微软的官网上下载 VS 2010 runtime libraries 解决该问题。具体地址为http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=5555

安装成功后在命令行里运行 pypy,输出结果如下:

C:\Documents and Settings\Administrator>pypy
 Python 2.7.2 (0e28b379d8b3, Feb 09 2012, 18:31:47)
 [PyPy 1.8.0 with MSC v.1500 32 bit] on win32
 Type "help", "copyright", "credits" or "license" for more information.
 And now for something completely different: ``PyPy is vast, and contains
 multitudes''
 >>>>

以清单 5 的循环为例子,使用 python 和 pypy 分别运行,得到的运行结果分别如下:

C:\Documents and Settings\Administrator\ 桌面 \doc\python>pypy loop.py
 total run time:
 8.42199993134
C:\Documents and Settings\Administrator\ 桌面 \doc\python>python loop.py
 total run time:
 106.391000032

可见使用 pypy 来编译和运行程序,其效率大大的提高。

  • Cython

Cython 是用 python 实现的一种语言,可以用来写 python 扩展,用它写出来的库都可以通过 import 来载入,性能上比 python 的快。cython 里可以载入 python 扩展 ( 比如 import math),也可以载入 c 的库的头文件 ( 比如 :cdef extern from “math.h”),另外也可以用它来写 python 代码。将关键部分重写成 C 扩展模块

Linux Cpython 的安装:

第一步:下载

[root@v5254085f259 cpython]# wget -N http://cython.org/release/Cython-0.15.1.zip
 --2012-04-16 22:08:35-- http://cython.org/release/Cython-0.15.1.zip
 Resolving cython.org... 128.208.160.197
 Connecting to cython.org|128.208.160.197|:80... connected.
 HTTP request sent, awaiting response... 200 OK
 Length: 2200299 (2.1M) [application/zip]
 Saving to: `Cython-0.15.1.zip'
100%[======================================>] 2,200,299 1.96M/s in 1.1s
2012-04-16 22:08:37 (1.96 MB/s) - `Cython-0.15.1.zip' saved [2200299/2200299]

第二步:解压

[root@v5254085f259 cpython]# unzip -o Cython-0.15.1.zip

第三步:安装

python setup.py install

安装完成后直接输入 cython,如果出现如下内容则表明安装成功。

[root@v5254085f259 Cython-0.15.1]# cython
Cython (http://cython.org) is a compiler for code written in the
Cython language.  Cython is based on Pyrex by Greg Ewing.

Usage: cython [options] sourcefile.{pyx,py} ...

Options:
 -V, --version                  Display version number of cython compiler
 -l, --create-listing           Write error messages to a listing file
 -I, --include-dir <directory>  Search for include files in named directory
                                (multiple include directories are allowed).
 -o, --output-file <filename>   Specify name of generated C file
 -t, --timestamps               Only compile newer source files
 -f, --force                    Compile all source files (overrides implied -t)
 -q, --quiet                    Don't print module names in recursive mode
 -v, --verbose                  Be verbose, print file names on multiple compil ation
 -p, --embed-positions          If specified, the positions in Cython files of each
 function definition is embedded in its docstring.
 --cleanup <level>
 Release interned objects on python exit, for memory debugging.
   Level indicates aggressiveness, default 0 releases nothing.
 -w, --working <directory>
 Sets the working directory for Cython (the directory modules are searched from)
 --gdb Output debug information for cygdb
 -D, --no-docstrings
             Strip docstrings from the compiled module.
 -a, --annotate
             Produce a colorized HTML version of the source.
 --line-directives
             Produce #line directives pointing to the .pyx source
 --cplus
             Output a C++ rather than C file.
 --embed[=<method_name>]
             Generate a main() function that embeds the Python interpreter.
 -2          Compile based on Python-2 syntax and code seman tics.
 -3          Compile based on Python-3 syntax and code seman tics.
 --fast-fail     Abort the compilation on the first error
 --warning-error, -Werror       Make all warnings into errors
 --warning-extra, -Wextra       Enable extra warnings
 -X, --directive <name>=<value>
 [,<name=value,...] Overrides a compiler directive

其他平台上的安装可以参考文档:http://docs.cython.org/src/quickstart/install.html

Cython 代码与 python 不同,必须先编译,编译一般需要经过两个阶段,将 pyx 文件编译为 .c 文件,再将 .c 文件编译为 .so 文件。编译有多种方法:
●通过命令行编译:

假设有如下测试代码,使用命令行编译为 .c 文件。

def sum(int a,int b):
        print a+b

 [root@v5254085f259 test]# cython sum.pyx
 [root@v5254085f259 test]# ls
 total 76
 4 drwxr-xr-x 2 root root  4096 Apr 17 02:45 .
 4 drwxr-xr-x 4 root root  4096 Apr 16 22:20 ..
 4 -rw-r--r-- 1 root root    35 Apr 17 02:45 1
 60 -rw-r--r-- 1 root root 55169 Apr 17 02:45 sum.c
 4 -rw-r--r-- 1 root root    35 Apr 17 02:45 sum.pyx

在 linux 上利用 gcc 编译为 .so 文件:

root@v5254085f259 test]# gcc -shared -pthread -fPIC -fwrapv -O2
-Wall -fno-strict-aliasing -I/usr/include/python2.4 -o sum.so sum.c
[root@v5254085f259 test]# ls
total 96
4 drwxr-xr-x 2 root root  4096 Apr 17 02:47 .
4 drwxr-xr-x 4 root root  4096 Apr 16 22:20 ..
4 -rw-r--r-- 1 root root    35 Apr 17 02:45 1
60 -rw-r--r-- 1 root root 55169 Apr 17 02:45 sum.c
4 -rw-r--r-- 1 root root    35 Apr 17 02:45 sum.pyx
20 -rwxr-xr-x 1 root root 20307 Apr 17 02:47 sum.so

●使用 distutils 编译
建立一个 setup.py 的脚本:

from distutils.core import setup
 from distutils.extension import Extension
 from Cython.Distutils import build_ext

 ext_modules = [Extension("sum", ["sum.pyx"])]

 setup(
    name = 'sum app',
    cmdclass = {'build_ext': build_ext},
    ext_modules = ext_modules
 )

 [root@v5254085f259 test]#  python setup.py build_ext --inplace
 running build_ext
 cythoning sum.pyx to sum.c
 building 'sum' extension
 gcc -pthread -fno-strict-aliasing -fPIC -g -O2 -DNDEBUG -g -fwrapv -O3
 -Wall -Wstrict-prototypes -fPIC -I/opt/ActivePython-2.7/include/python2.7
  -c sum.c -o build/temp.linux-x86_64-2.7/sum.o
 gcc -pthread -shared build/temp.linux-x86_64-2.7/sum.o
 -o /root/cpython/test/sum.so

译完成之后可以导入到 python 中使用:

[root@v5254085f259 test]# python
ActivePython 2.7.2.5 (ActiveState Software Inc.) based on
Python 2.7.2 (default, Jun 24 2011, 11:24:26)
[GCC 4.0.2 20051125 (Red Hat 4.0.2-8)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyximport; pyximport.install()
>>> import sum
>>> sum.sum(1,3)

下面来进行一个简单的性能比较:

清单 9. Cython 测试代码

from time import time
 def test(int n):
 cdef int a =0
 cdef int i
 for i in xrange(n):
 a+= i
 return a
t = time()
 test(10000000)
 print "total run time:"
 print time()-t

测试结果:

[GCC 4.0.2 20051125 (Red Hat 4.0.2-8)] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
 >>> import pyximport; pyximport.install()
 >>> import ctest
 total run time:
 0.00714015960693

清单 10. Python 测试代码

from time import time
 def test(n):
 a =0;
 for i in xrange(n):
 a+= i
 return a
t = time()
 test(10000000)
 print "total run time:"
 print time()-t
[root@v5254085f259 test]# python test.py
 total run time:
 0.971596002579

从上述对比可以看到使用 Cython 的速度提高了将近 100 多倍。

总结

本文初步探讨了 python 常见的性能优化技巧以及如何借助工具来定位和分析程序的性能瓶颈,并提供了相关可以进行性能优化的工具或语言,希望能够更相关人员一些参考。

Python十分钟入门

转载于:《Linux大棚》博客,博客地址为http://roclinux.cn。文章作者为Rocrocket Wu。

Python十分钟入门

简介

Python是一种动态解释型的编程语言。Python可以在Windows、UNIX、MAC等多种操作系统上使用,也可以在Java、.NET开发平台上使用。

特点

1 Python使用C语言开发,但是Python不再有C语言中的指针等复杂的数据类型。

2 Python具有很强的面向对象特性,而且简化了面向对象的实现。它消除了保护类型、抽象类、接口等面向对象的元素。

3 Python代码块使用空格或制表符缩进的方式分隔代码。

4 Python仅有31个保留字,而且没有分号、begin、end等标记。

5 Python是强类型语言,变量创建后会对应一种数据类型,出现在统一表达式中的不同类型的变量需要做类型转换。

搭建开发环境

1 可以到www.python.org下载安装包,然后通过configure、make、make install进行安装。

2 也可以到www.activestate.com去下载ActivePython组件包。(ActivePython是对Python核心和常用模块的二进制包装,它是ActiveState公司发布的Python开发环境。ActivePython使得Python的安装更加容易,并且可以应用在各种操作系统上。ActivePython包含了一些常用的Python扩展,以及Windows环境的编程接口)。对ActivePython来说,如果你是windows用户,下载msi包安装即可;如果你是Unix用户,下载tar.gz包直接解压即可。

3 Python的IDE,包括Pycharm、PythonWin、Eclipse+PyDev插件、Komodo、EditPlus

版本

python2与python3是目前主要的两个版本。

如下两种情况下,建议使用python2:

1 你无法完全控制你即将部署的环境时;

2 你需要使用一些特定的第三方包或扩展时;

python3是官方推荐的且是未来全力支持的版本,目前很多功能提升仅在python3版本上进行。

hello world

1 创建hello.py
2 编写程序:

  if __name__ == \'__main__\':   
      print "hello word"  

运行程序:

  python ./hello.py  

注释

1 无论是行注释还是段注释,均以#加一个空格来注释。

2 如果需要在代码中使用中文注释,必须在python文件的最前面加上如下注释说明:

    # -* - coding: UTF-8 -* -

3 如下注释用于指定解释器

    #! /usr/bin/python

文件类型

  • Python的文件类型分为3种,即源代码、字节代码和优化代码。这些都可以直接运行,不需要进行编译或连接。
  • 源代码以.py为扩展名,由python来负责解释;
  • 源文件经过编译后生成扩展名为.pyc的文件,即编译过的字节文件。这种文件不能使用文本编辑器修改。pyc文件是和平台无关的,可以在大部分操作系统上运行。如下语句可以用来产生pyc文件:
import py_compile
py_compile.compile('hello.py')
  • 经过优化的源文件会以.pyo为后缀,即优化代码。它也不能直接用文本编辑器修改,如下命令可用来生成pyo文件:
python -O -m py_complie hello.py

变量

1 python中的变量不需要声明,变量的赋值操作即使变量声明和定义的过程。

2 python中一次新的赋值,将创建一个新的变量。即使变量的名称相同,变量的标识并不相同。用id()函数可以获取变量标识:

x = 1
print id(x)
x = 2
print id(x)

3 如果变量没有赋值,则python认为该变量不存在

4 在函数之外定义的变量都可以称为全局变量。全局变量可以被文件内部的任何函数和外部文件访问。

5 全局变量建议在文件的开头定义。

6 也可以把全局变量放到一个专门的文件中,然后通过import来引用:

gl.py文件中内容如下:

_a = 1
_b = 2

use_global.py中引用全局变量:

import gl
def fun():
  print gl._a
  print gl._b
fun()

常量

python中没有提供定义常量的保留字。可以自己定义一个常量类来实现常量的功能。

class _const:
  class ConstError(TypeError): pass
    def __setattr__(self,name,vlaue):
      if self.__dict__.has_key(name):
        raise self.ConstError, "Can't rebind const(%s)"%name
        self.__dict__[name]=value
import sys
sys.modules[__name__]=_const()

数据类型

  1. python的数字类型分为整型、长整型、浮点型、布尔型、复数类型。
  2. python没有字符类型
  3. python内部没有普通类型,任何类型都是对象。
  4. 如果需要查看变量的类型,可以使用type类,该类可以返回变量的类型或创建一个新的类型。
  5. python有3种表示字符串类型的方式,即单引号、双引号、三引号。单引号和双引号的作用是相同的。python程序员更喜欢用单引号,C/Java程序员则习惯使用双引号表示字符串。三引号中可以输入单引号、双引号或换行等字符。

运算符和表达式

1 python不支持自增运算符和自减运算符。例如i++/i-是错误的,但i+=1是可以的。

2 1/2在python2.5之前会等于0.5,在python2.5之后会等于0。

3 不等于为!=或<>

4 等于用==表示

5 逻辑表达式中and表示逻辑与,or表示逻辑或,not表示逻辑非

控制语句

1 条件语句:

if (表达式) :
    语句1
else :
    语句2

2 条件语句:

if (表达式) :
  语句1
elif (表达式) :
  语句2elif (表达式) :
  语句n
else :
  语句m

3 条件嵌套:

if (表达式1) :
  if (表达式2) :
    语句1
  elif (表达式3) :
    语句2else:
    语句3
elif (表达式n) :
   …
else :
   …

4 python本身没有switch语句。

5 循环语句:

while(表达式) :
   …
else :
   …

6 循环语句:

for 变量 in 集合 :
   …
else :
   …

7 python不支持类似c的for(i=0;i<5;i++)这样的循环语句,但可以借助range模拟:

for x in range(0,5,2):
    print x

数组相关

1 元组(tuple):python中一种内置的数据结构。元组由不同的元素组成,每个元素可以存储不同类型的数据,如字符串、数字甚至元素。元组是写保护的,即元组创建之后不能再修改。元组往往代表一行数据,而元组中的元素代表不同的数据项。可以把元组看做不可修改的数组。创建元组示例如下:

tuple_name=('apple','banana','grape','orange')

2 列表(list):列表和元组相似,也由一组元素组成,列表可以实现添加、删除和查找操作,元素的值可以被修改。列表是传统意义上的数组。列表创建示例如下:

list=['apple','banana','grage','orange']

可以使用append方法来在尾部追加元素,使用remove来删除元素。

3 字典(dictionary):由键-值对组成的集合,字典中的值通过键来引用。键和值之间用冒号隔开,键-值对之间用逗号隔开,并且被包含在一对花括号中。创建示例如下:

dict={'a':'apple', 'b':'banana', 'g':'grage', 'o':'orange'}

4 序列:序列是具有索引和切片能力的集合。元组、列表和字符串都属于序列。

函数相关

1 python程序由包(package)、模块(module)和函数组成。包是由一系列模块组成的集合。模块是处理某一类问题的函数和类的集合。

2 包就是一个完成特定任务的工具箱。

3 包必须含有一个init.py文件,它用于标识当前文件夹是一个包。

4 python的程序是由一个个模块组成的。模块把一组相关的函数或代码组织到一个文件中,一个文件即是一个模块。模块由代码、函数和类组成。导入模块使用import语句。

5 包的作用是实现程序的重用。

6 函数是一段可以重复多次调用的代码,函数定义示例如下:

def arithmetic(x,y,operator):
   result={
      '+':x+y,
      '-':x-y,
      '*':x*y,
      '/':x/y
   }

7 函数返回值可以用return来控制。

字符串相关

1 格式化输出:

format='%s%d' % (str1,num)
print format

2 用+进行字符串的合并:

str1='hello'
str2='world'
result=str1+str2

3 字符串截取可以通过索引/切片,也可以通过split函数。

4 通过切片截取字符串:

word='world'
print word[0:3]

5 python使用==和!=来进行字符串比较。如果比较的两个变量的类型不相同,那么结果必然为不同。

文件处理

1 简单处理文件:

context='hello,world'
f=file('hello.txt','w')
f.write(context);
f.close()

2 读取文件可以使用readline()函数、readlines()函数和read函数。

3 写入文件可以使用write()、writelines()函数

对象和类

1 python用class保留字来定义一个类,类名的首字符要大写。当程序员需要创建的类型不能用简单类型来表示时,就需要定义类,然后利用定义的类创建对象。定义类示例:

class Fruit:
    def grow(self):
       print 'Fruit grow'

2 当一个对象被创建后,包含了三方面的特性,即对象的句柄、属性和方法。创建对象的方法:

fruit = Fruit()
fruit.grow()

3 python没有保护类型的修饰符 (只能用于它们自已的类和子类中)。类方法或者是私有 (只能在它们自已的类中使用) 或者是公有 (任何地方都可使用)。

4 类的方法也分为公有方法和私有方法。私有函数不能被该类之外的函数调用,私有的方法也不能被外部的类或函数调用。与大多数的语言不同,一个 Python 函数,方法,或属性是私有还是公有,完全取决于它的名字。如果一个 Python 函数,类方法,或属性的名字以两个下划线开始 (但不是结束),它是私有的;其它所有的都是公有的。

5 python使用函数”staticmethod()“或”@ staticmethod“指令的方法把普通的函数转换为静态方法。静态方法相当于全局函数。

6 python的构造函数名为init,析构函数名为del

7 继承的使用方法:

class Apple(Fruit):
   def

连接mysql

1 用MySQLdb模块操作MySQL数据库非常方便。示例代码如下:

import os, sys
import MySQLdb
try:
    conn MySQLdb.connect(host='localhost',user='root',passwd='',db='address'
except Exception,e:
    print e
    sys.exit()
cursor=conn.cursor()
sql='insert into address(name, address) values(%s, %s)'
value=(('zhangsan','haidian'),('lisi','haidian'))
try
    cursor.executemany(sql,values)
except Exception, e:
    print e
sql='select * from address'
cursor.execute(sql)
data=cursor.fetchall()
if data
    for x in data:
        print x[0],x[1]
cursor.close()
conn.close()

结束谢谢!

如何成为Python高手

转自:How to become a proficient Python programmer
我的总结主要集中在四个基本题目上:函数式编程,性能,测试,编码规范。如果一个程序员能将这四个方面的内容知识都吸收消化,那他/她不管怎样都会有巨大的收获。
函数式编程

命令式的编程风格已经成为事实上的标准。命令式编程的程序是由一些描述状态转变的语句组成。虽然有时候这种编程方式十分的有效,但有时也不尽如此(比如复杂性) —— 而且,相对于声明式编程方式,它可能会显得不是很直观。

如果你不明白我究竟是在说什么,这很正常。这里有一些文章能让你脑袋开窍。但你要注意,这些文章有点像《骇客帝国》里的红色药丸 —— 一旦你尝试过了函数式编程,你就永远不会回头了。
http://www.amk.ca/python/writing/functional
http://www.secnetix.de/olli/Python/lambda_functions.hawk
http://docs.python.org/howto/functional.html

性能

你会看到有如此多的讨论都在批评这些“脚本语言”(Python,Ruby)是如何的性能低下,可是你却经常的容易忽略这样的事实:是程序员使用的算法导致了程序这样拙劣的表现。

这里有一些非常好的文章,能让你知道Python的运行时性能表现的细节详情,你会发现,通过这些精炼而且有趣的语言,你也能写出高性能的应用程序。而且,当你的老板质疑Python的性能时,你别忘了告诉他,这世界上第二大的搜索引擎就是用Python写成的 —— 它叫做Youtube(参考Python摘录)
http://jaynes.colorado.edu/PythonIdioms.html
http://wiki.python.org/moin/PythonSpeed/PerformanceTips

测试

如今在计算机科学界,测试可能是一个最让人不知所措的主题了。有些程序员能真正的理解它,十分重视TDD(测试驱动开发)和它的后继者BDD(行为驱动开发)。而另外一些根本不接受,认为这是浪费时间。那么,我现在将告诉你:如果你不曾开始使用TDD/BDD,那你错过了很多最好的东西!

这并不只是说引入了一种技术,可以替换你的公司里那种通过愚蠢的手工点击测试应用程序的原始发布管理制度,更重要的是,它是一种能够让你深入理解你自己的业务领域的工具 —— 真正的你需要的、你想要的攻克问题、处理问题的方式。如果你还没有这样做,请试一下。下面的这些文章将会给你一些提示:
http://www.oreillynet.com/lpt/a/5463
http://www.oreillynet.com/lpt/a/5584
http://wiki.cacr.caltech.edu/danse/index.php/Unit_testing_and_Integration_testing
http://docs.python.org/library/unittest.html

编码规范

并非所有的代码生来平等。有些代码可以被另外的任何一个好的程序员读懂和修改。但有些却只能被读,而且只能被代码的原始作者修改 —— 而且这也只是在他或她写出了这代码的几小时内可以。为什么会这样?因为没有经过代码测试(上面说的)和缺乏正确的编程规范。

下面的文章给你描述了一个最小的应该遵守的规范合集。如果按照这些指导原则,你将能编写出更简洁和漂亮的代码。作为附加效应,你的程序会变得可读性更好,更容易的被你和任何其他人修改。
http://www.python.org/dev/peps/pep-0008/
http://www.fantascienza.net/leonardo/ar/python_best_practices.html

那就去传阅这这些资料吧。从坐在你身边的人开始。也许在下一次程序员沙龙或编程大会的时候,也已经成为一名Python编程高手了!

祝你学习旅途顺利。

如果你喜欢这些文章,请在微博上顶一下,让其他人也知道。

给Python初学者的一些技巧

转自:英文原文:Max Burstein,编译:伯乐在线 –刘志军

以下是收集的一些Python实用技巧和工具,希望能对你有所帮助。

交换变量

x = 6
y = 5
x, y = y, x
print x
>>> 5
print y
>>> 6

if 语句在行内

print "Hello" if True else "World"
>>> Hello

连接

下面的最后一种方式在绑定两个不同类型的对象时显得很cool。

nfc = ["Packers", "49ers"]
afc = ["Ravens", "Patriots"]
print nfc + afc
>>> ['Packers', '49ers', 'Ravens', 'Patriots']

print str(1) + " world"
>>> 1 world

print `1` + " world"
>>> 1 world

print 1, "world"
>>> 1 world
print nfc, 1
>>> ['Packers', '49ers'] 1

数字技巧

#除后向下取整
print 5.0//2
>>> 2
# 2的5次方
print 2**5
>> 32

注意浮点数的除法

print .3/.1
>>> 2.9999999999999996
print .3//.1
>>> 2.0

数值比较

x = 2
if 3 > x > 1:
   print x
>>> 2
if 1 < x > 0:
   print x
>>> 2

同时迭代两个列表

nfc = ["Packers", "49ers"]
afc = ["Ravens", "Patriots"]
for teama, teamb in zip(nfc, afc):
     print teama + " vs. " + teamb
>>> Packers vs. Ravens
>>> 49ers vs. Patriots

带索引的列表迭代

teams = ["Packers", "49ers", "Ravens", "Patriots"]
for index, team in enumerate(teams):
    print index, team
>>> 0 Packers
>>> 1 49ers
>>> 2 Ravens
>>> 3 Patriots

列表推导式

已知一个列表,我们可以刷选出偶数列表方法:

numbers = [1,2,3,4,5,6]
even = []
for number in numbers:
    if number%2 == 0:
        even.append(number)

转变成如下:

numbers = [1,2,3,4,5,6]
even = [number for number in numbers if number%2 == 0]

字典推导

和列表推导类似,字典可以做同样的工作:

teams = ['Packers', '49ers', 'Ravens', 'Patriots']
print {key: value for value, key in enumerate(teams)}
>>> {'49ers': 1, 'Ravens': 2, 'Patriots': 3, 'Packers': 0}

初始化列表的值

items = [0]*3
print items
>>> [0,0,0]

列表转换为字符串

teams = ["Packers", "49ers", "Ravens", "Patriots"]
print ", ".join(teams)
>>> 'Packers, 49ers, Ravens, Patriots'

从字典中获取元素

我承认try/except代码并不雅致,不过这里有一种简单方法,尝试在字典中查找key,如果没有找到对应的alue将用第二个参数设为其变量值。

data = {'user': 1, 'name': 'Max', 'three': 4}
try:
   is_admin = data['admin']
except KeyError:
   is_admin = False

替换诚这样:

data = {'user': 1, 'name': 'Max', 'three': 4}
is_admin = data.get('admin', False)

获取列表的子集

有时,你只需要列表中的部分元素,这里是一些获取列表子集的方法。

x = [1,2,3,4,5,6]
#前3个
print x[:3]
>>> [1,2,3]
#中间4个
print x[1:5]
>>> [2,3,4,5]
#最后3个
print x[-3:]
>>> [4,5,6]
#奇数项
print x[::2]
>>> [1,3,5]
#偶数项
print x[1::2]
>>> [2,4,6]

60个字符解决FizzBuzz

前段时间Jeff Atwood 推广了一个简单的编程练习叫FizzBuzz,问题引用如下:

写一个程序,打印数字1到100,3的倍数打印“Fizz”来替换这个数,5的倍数打印“Buzz”,对于既是3的倍数又是5的倍数的数字打印“FizzBuzz”。

这里就是一个简短的,有意思的方法解决这个问题:

for x in range(101):print"fizz"[x%3*4::]+"buzz"[x%5*4::]or x

集合

除了python内置的数据类型外,在collection模块同样还包括一些特别的用例,在有些场合Counter非常实用。如果你参加过在这一年的Facebook HackerCup,你甚至也能找到他的实用之处。

from collections import Counter
print Counter("hello")
>>> Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})

迭代工具

和collections库一样,还有一个库叫itertools,对某些问题真能高效地解决。其中一个用例是查找所有组合,他能告诉你在一个组中元素的所有不能的组合方式

from itertools import combinations
teams = ["Packers", "49ers", "Ravens", "Patriots"]
for game in combinations(teams, 2):
    print game
>>> ('Packers', '49ers')
>>> ('Packers', 'Ravens')
>>> ('Packers', 'Patriots')
>>> ('49ers', 'Ravens')
>>> ('49ers', 'Patriots')
>>> ('Ravens', 'Patriots')

False == True

比起实用技术来说这是一个很有趣的事,在python中,True和False是全局变量,因此:

False = True
if False:
   print "Hello"
else:
   print "World"
>>> Hello

如果你还有任何很酷的奇技淫巧,可以在下面留言,感谢阅读。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.