首页 > 代码库 > Python学习指南

Python学习指南

学习python书籍&资料:

1. Python v2.7.5 documentation

2. [Python参考手册(第4版)].(美)比兹利.扫描版.pdf

3. [Python技术手册(第2版)].(美)马特利.扫描版.pdf

4. Python标准库.pdf

5. [Python.Unix和Linux系统管理指南].(美)基弗特.扫描版.pdf
---------------------------------------

设计目标:

    grep-->sed-->awk-->perl-->python, 提供更方便的脚本语言.

运行机制:

    一种解释型的脚本语言. 所谓解释型语言, 都是先将源码编译成中间字节码, 中间字节码再在虚拟机上运行. 有别于编译型语言, 直接将源码编译成本地机器码运行.

语言特色:

    语法比perl简单, 支持面向对象

语法类库:

1. 字符集

    Python源码文件默认是Latin-1字符集, 可使用编码注释:#coding:UTF-8指定字符编码. 至于虚拟机运行时字符集, 需用sys.setdefaultencoding()函数. 以下是python程序的起式:

          #coding:utf-8

from __future__ import(absolute_import, generators, unicode_literals, print_function, nested_scopes, with_statement)

import sys

if sys.getdefaultencoding!=‘utf-8‘:

reload(sys)

sys.setdefaultencoding( "utf-8" )

print("这是一个测试")

2. 词汇

    (1)Keyword

        Python的关键字分类:

            and                del            from            nonlocal    try

            as                   elif            global         not             while

            assert             else           if                 or                with

            break             except       import        pass            yield

            class               exec          in                print

            continue        finally       is                 raise

            def                 for             lambda       return

        声明引入: class, def, lambda, global, nonlocal, import-as, from-import-as, with-as

        控制语句: 

            条件选择: if-elif-else, 

            循环迭代: while-else, for-in-else

            跳转中断: break, continue, return, raise. 不支持带标签.

            异常捕获: try-except-else-finally 

        运算符:

            逻辑关系: not, and, or, in, is

            特殊操作: assert, exec, pass, print, yield

    (2)Identifier

        Python的标识符: 由字母,数字,下划线_组成, 并且不能数字开头, 不能是关键字. 其中下划线打头具有特殊含义:

        _在交互式环境表示最后表达式的值.

        包私有模块在__init__.py中的__all__不声明.

        模块私有变量以单下划线打头.

        类私有变量以双下划线打头, 由编译器自动转成__classame__fieldname.

    (3)Literal

        表示数据:

            None类型: None

            Number类型:

                bool: True, False

                int: 8进制0前缀, 10进制无前缀, 16进制0x或0X前缀.

                long: l或L后缀

                float: 小数形式, 指数形式.        

                complex: R+Mj 或 R+MJ

            Seq类型:

                str: base string单引, 双引或三引括住的字符序列. raw string是r前缀, 且不能以奇数个/结尾. unicode string是u前缀. 

                        标准的转义字符:

                        \    续行符

                        \\    斜杠

                        \‘    单引

                        \"    双引

                        \a    bell

                        \b    退格

                        \e    Escape

                        \0    Null(空值)

                        \n    换行

                        \r    回车

                        \v    垂直制表

                        \t    水平制表

                        \f    换页

                        \000    三位8进制表示的ASCII字符

                        \xhh    二位16进制表示的ASCII字符

                        \uhhhh    四位16进制表示的Unicode字符

                        \Uhhhhhhhh 八位16进制表示的Unicode字符

                list: [...]

                tuple: (...), 其中0-元组, 1-元组, n-元组中1-元组必须带逗号",",否则误为函数调用.

            Dict类型:

                dict: {k:v}, 其中key为immutable类型, value为任意类型.

            Function:

                Python没有函数直接量, 只用lambda表达式作为妥协物.

    (4)Operator

            Python的运算符可分为:

            算术运算符(包括位运算符): +, -, *, /, %, //, **, Python没有++,--自运算符.

            关系运算符: ==, !=, >, >=, <, <=

            逻辑运算符: not, and, or

            位运算符: ~, &, |, <<, >>

            赋值运算符: 简单赋值=, 复合赋值(跟算术,位复合).

            特殊运算符:

                Python没有三元运算符, 只有条件赋值表达式: whenTrue if condition else whenFalse

    (5)Comment

            Python只有#注释符, 多行注释需要借助三引字符串.

            Python的文档注释位于目标定义的首行, 例如:模块文档在模块体首行,即import之前, 函数文档或函数体首行.

    (6)Limiter

           一行多个语句需用分号";"隔开. 多行一个语句需用续行符"\"注释换行符.

3. 数据类型,变量,常量,直接量

Python的数据类型可分为:

(1)表示数据

None类型: None

Number类型:

bool: True, False

int: 8进制0前缀,10进制无前缀,16进制0x或0X前缀

long: L或l后缀

float: 没有double类型

complex: r+mj或r+mJ

Seq类型:

str: Python的string有3种:

base string: 单引, 双引, 三引. Python中单引,双引没有区别.

raw string: r前缀, raw string不能以奇数个‘\‘结尾.

unicode string: u前缀.

                                注意: 要记住转义字符表.

list: [...]

tuple: (...), 0元组(), 1元组(a,), 多元组(a,b). 其中1元组后必须有逗号,否则视作函调用. 例子: 

a=()#0-元组(空元组)

b=(item,)#1-元组(注意随后的逗号)

c=item,#1-元组(注意随后的逗号)

其中,Seq类型的公共操作:index, slice, join, repeat, in, len, min, max

Set类型:

set: 必须使用set(Seq)构造

frozenset: 必须使用frozenset(Seq)构造,注意:frozen不是frozent,其后没有t.

Dict类型:

dict: {k:v}, 其中k必须为immutable对象, v任意类型.

删除元素使用del prices["MSFT"]

(2)表示程序

types.PackageType

types.ModuleType

type

object

types.BuiltinFunctionType, types.FunctionType, types.MethodType

(3)表示实现

types.CodeType

types.FrameType

types.GeneratorType

types.TracebackType

slice

Ellipsis

XRange

4. 运算符,内置函数,表达式

运算符:

del

5. 语句

    表达式语句

    空语句

    复合语句或语句块

    控制语句

         条件选择

if-elif-else, 没有选择语句

         循环迭代

while循环, 

for-in迭代: for var in iterable: statements

迭代相关函数range(start=0,stop,step=1), xrange(start=0,stop,step=1), enumerate(Seq), zip(Seq,Seq)

         跳转中断

break, continue, return, raise

         异常捕获

try-except-else-finally-raise, 其中else子句与while-else, for-else中的意义一样.在中间没有流程跳转时将会执行.

         其他……

6. 函数

(1)函数定义:def func_name(param_list): statements

(2)形数声明: 普通参数, 默认参数, *参数, **参数

注意: 参数声明时的位置, 普通参数 < 默认参数 < *参数 < **参数, 即默认参数必须在普通参数后, *参数必须在默认参数后, **参数必须在*参数后. 否则报错!

        (3)实参传递: 位置传递,命名传递,*运算符, **运算符

(4)多值返回: 借助tuple类型,python函数可以返回多值.

        (5)函数闭包: closure

7. 面向对象: 元类, 类, 实例, 引用, 对象, 域, 属性, 方法, 继承, 改写

        定义属性的三种方法:

            (1)property(getter,setter,deleter)函数

            (2)@property, @xxx.setter, @xxx.deleter注解

            (3)PropertyDescriptor:

                    def __get__(self,instance,cls)

                    def __set__(self,instance,value)

                    def __delete__(self,instance)

                    其中instance是属性实例, 其将描述符与属性访问机制挂钩.

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

        (0)metaclass, class, object的区别.

        (1)python的一切值都是对象, 对象都有id, type, value.

        (2)对象由域(field), 属性(property), 方法(method)组成, 这些元素又可分成类级,实例级,局部级(函数内)

        (3)内置域, 属性, 方法又称魔术(magic)域, 属性, 方法.

        (4)用户定义域, 属性, 方法.

        (5)对象模型: 旧对象模型, 新对象模型, 区别在于metaclass不同, 导致实例对象过程不同.

        (6)实例创建过程: instance=C.metaclass.__new__(C,*args,**kvargs) -->instance.__init__(*args,**kvargs);

        (7)属性或域查找过程: 

        (8)super函数及局限.

        其他理解:

        (1)python的一切值都是对象,是对象都id,type,value. 是对象也有域,属性,方法. Python中类型接口的概念就是一组特殊方法集(首尾是双下划线), 在golang借用了此构想. 实现这些特殊方法, 也就定义了类型的运算行为, 即C++中重载运算符的概念. 简单地说, python的运算行为由对象的特殊方法决定, 通过改写特殊方法实现重载运算符.

        (2)Python没有new运算符, 因为type, object都是可调用对象.

8. 高级特性技巧

(1)字串格式的三种方法:

格式符%,

format()方法,

string.Template()类

(2)print语句后面跟‘,‘将忽略换行符. print()函数则用end=‘‘忽略换行符.

(3)版本特性兼容:from __future__ import (absolute_import, division, generators, unicode_literals, print_function, nested_scopes, with_statement)

(4)input()和raw_input()的区别: eval(raw_input(prompt))

(5)repr()和str()的区别: repr()输出内部字串, str()输出友好字串.通过__str__()成员控制其行为.该成员不存在,则使用其 __repr__()成员

(6)列表解析(List Comprehension): [expression for-statement if-statment]

(7)生成器表达式(Generator Expression): (expression for-statement if-statment)

(8)yield表达式原理, Generator, Coroutine: 

调用包含yield表达式的函数会创建Generator.

Generator在单独的协程(Coroutine)执行.

Generator包含next(), send(V), throw(E), close()方法. 其中next()等价send(None).

调用Generator.next()或Generator.send(V)会使函数流程执行到下一个yield表达式, 并返回yield表达式的值.

再次调用Generator.send(V)则用参数值V替换yield表达式的值继续执行到下一个yield表达式.直到函数结束.

        (9)装饰器decodrator: 装饰器是AOP一种实现. 其采用函数闭包的形式实现. 

                根据目标可分为: 类装饰器, 函数装饰器. 即接收参数为类或函数

                根据参数可分为: 无参装饰器, 带参装饰器. 即是否定义函数, 带参数装饰器在无参装饰器外层套多一层闭包!

9. 包, 模块, 标准库

    Python使用包与模块的概念管理命名空间,组织源码.

    包: 包含__init__.py的目录.

    模块: 文件.

    标准库:

        (1)文件操作: open, read/write, close.是否需要try-except-else-finally

        (2)BaseException异常类层次

(3)sys模块

10. 编译, 执行, 调试

    环境变量

    命令行及选项

11. 设计模式

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

其他杂症:

1.字符集的问题:

一旦使用unicode_literals则 isinstance("abc",str)会是False. 因为此时"abc"已经是unicode,不再是str.务必注意.

#-*- coding:utf-8 -*-

from __future__ import(absolute_import,division,generators,unicode_literals,print_function,nested_scopes,with_statement)

import sys

class TypedProperty(object):

def __init__(self,name,type,default=None):

self.name=‘_‘+name

self.type=type

self.default=default if default else type()

def __get__(self,instance,cls):

return getattr(instance,self.name,self.default)

def __set__(self,instance,value):

if not isinstance(value,self.type):

raise TypeError("Must be %s" % self.type)

setattr(instance,self.name,value)

def __delete__(self,instance):

raise AttributeError("Can‘t delte attribute")

class Foo(object):

name=TypedProperty("name",unicode)

num=TypedProperty("num",int,43)

def test():

f=Foo()

a=f.name

f.name="Guido"

print(f.name)

del f.name

if __name__=="__main__":

if sys.getdefaultencoding()!="utf-8":

reload(sys)

sys.setdefaultencoding(‘utf-8‘);

test()

#print(isinstance("Geios",unicode))

2. 包的私有模块,不在__init__.py的__all__中列出

    模块的私有属性

    类的私有属性

    实例的私有属性, 以双下划线开头, 自动转在_ClassName__Attribute的形式.何苦?

3. 异常处理

    (1)错前判定

    (2)错后捕获

    至于使用哪种策略,视代码错误的频度而定,对于经常出错的代码使用错前判定,可以减少错误捕获的耗费,节省开支;对于不经常出错的代码使用错后捕获,可以减少if的执行,更节省开支.

4. Python的优化策略

    (1)理解程序:

        a. 选择最优的算法: 糟糕的O(n logn)算法比优化的O(n3)算法性能更好. 总是选择更好的算法,不要尝试优化差的算法.

        b. 使用内置类型: Python的内置类型list, tuple, set, dict都是用C实现的,而且经过解释器优化的数据结构. 尽量使用内置类型, 避免自定义类型.

    (2)不要添加层:

        其原则与(1),(5)中的原理一样.

    (3)了解如何基于字典构建类和实例

        其原则与(1)相同.

    (4)使用__slot__

    (5)避免使用(.)运算符

    (6)使用异常处理不常见的情况

    (7)避免对常见的情况使用异常

    (8)鼓励函数编程和迭代

        列表包含, 生成器表达式, 生成器, 协和和闭包比大多数Python程序员想象的更为高效.

    (9)使用装饰器和元类

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

     Python优化总结:

    (0)优先考虑优化算法,而非盲目优化代码: 瘦死的骆驼比马大!

    (1)优先考虑内置类型,而非构建类与实例

            Python内置类型list,tuple,set,dict是用C实现,而且经过解释器优化的数据结构. 基于dict可以构建类与实例的效果, 而且性能更优.

    (2)优先考虑__slot__,而非__dict__

            Python类使用__slot__比__dict__性能更优.

    (3)优先考虑函数编程与迭代, 而非抽象继承.

            Python的基础设备: list comprehension, generator expression, generator, coroutine, closure等比使用函数递归, 循环遍历性能更优, 更加高效.

    (4)避免属性查找运算(.)

            Python名称查询是要损耗性能的.

    (5)避免滥用异常

            错误处理策略有二类: 错前预防, 错后补救. 在Python中就是错前if, 错后except. 

            如果异常频率低, 使用if判定会浪费很多性能.

            如果异常频率高, 使用try-except捕获会浪费很多性能.

            所以, 如果异常频率高, 使用if, 避免try-except处理耗时; 如果异常频率低,使用try-except,避免if的浪费.

===============================================

开发, 调试和测试

1. 搭建Python开发环境: eclipse+pydev

2. python命令行及选项

usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...

Options and arguments (and corresponding environment variables):

-B : don‘t write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x

-c cmd : program passed in as string (terminates option list)

-d : debug output from parser; also PYTHONDEBUG=x

-E : ignore PYTHON* environment variables (such as PYTHONPATH)

-h : print this help message and exit (also --help)

-i : inspect interactively after running script; forces a prompt even

         if stdin does not appear to be a terminal; also PYTHONINSPECT=x

-m mod : run library module as a script (terminates option list)

-O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x

-OO : remove doc-strings in addition to the -O optimizations

-R : use a pseudo-random salt to make hash() values of various types be

         unpredictable between separate invocations of the interpreter, as

         a defense against denial-of-service attacks

-Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew

-s : don‘t add user site directory to sys.path; also PYTHONNOUSERSITE

-S : don‘t imply ‘import site‘ on initialization

-t : issue warnings about inconsistent tab usage (-tt: issue errors)

-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x

         see man page for details on internal buffering relating to ‘-u‘

-v : verbose (trace import statements); also PYTHONVERBOSE=x

         can be supplied multiple times to increase verbosity

-V : print the Python version number and exit (also --version)

-W arg : warning control; arg is action:message:category:module:lineno

         also PYTHONWARNINGS=arg

-x : skip first line of source, allowing use of non-Unix forms of #!cmd

-3 : warn about Python 3.x incompatibilities that 2to3 cannot trivially fix

file : program read from script file

- : program read from stdin (default; interactive mode if a tty)

arg ...: arguments passed to program in sys.argv[1:]

Other environment variables:

PYTHONSTARTUP: file executed on interactive startup (no default)

PYTHONPATH : ‘:‘-separated list of directories prefixed to the

               default module search path. The result is sys.path.

PYTHONHOME : alternate <prefix> directory (or <prefix>:<exec_prefix>).

               The default module search path uses <prefix>/pythonX.X.

PYTHONCASEOK : ignore case in ‘import‘ statements (Windows).

PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.

PYTHONHASHSEED: if this variable is set to ‘random‘, the effect is the same

   as specifying the -R option: a random value is used to seed the hashes of

   str, bytes and datetime objects. It can also be set to an integer

   in the range [0,4294967295] to get hash values with a predictable seed.

选项分类:

第一类: 执行方式

    (1) -c: command, 执行命令

    (2) -i: interactive, 执行交互

    (3) -m: module, 执行模块

    (4) file: 执行文件

    (5) -: 执行流

    (6) -d: debug模式

    (7) -v:  PYTHONVERBOSE, 详细输出

第二类: 源码编译

    (1) -B: PYTHONDONTWRITEBYTECODE, 不保存编译后的字节码.

    (2) -E: ignore PYTHON* environment.

    (3) -O, -OO: PYTHONOPTIMIZE, optimize

    (4) -s, -S: PYTHONNOUSERSITE, don‘t add user site, don‘t apply import site.

    (5) -t, -tt: Tab与空格共用

    (6) -x: skip x line

    (7) -3: 兼容python3的方式

第三类: 特性设置

    (1) -R: hash()方法

    (2) -Q: 除法

    (3) -u: PYTHONUNBUFFERED

第四类: 其他:

    (1) -h

    (2) -V

环境变量:

    PYTHONHOME: python的home目录 

    PYTHONPATH: python的类路径

    PYTHONSTARTUP: python启动时的执行命令,如果@打头,则认为是脚本文件.

    PYTHONIOENCODING

    PYTHONHASHSEED

    python启动时指定stdout, stderr, stdin的编码, hash的随机种子. PYTHONIOENCODING比较关键.

所以, 在脚本启动python的方式一般为:

    env - PYTHONIOENCODING=utf8 python xxx

或在main模块中设置:

3. python交互退出:

    (1) EOF: Ctrl+Z, Ctrl+D

    (2) exit()函数

    (3) raise SystemExit

Python学习指南