netoxi

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  27 Posts :: 0 Stories :: 19 Comments :: 0 Trackbacks

目录

· 概况

· 安装

· 基础

    · 基础语法

    · 数据类型

    · 变量

    · 常量

    · 字符编码

    · 字符串格式化

    · list

    · tuple

    · dict

    · set

    · if语句

    · for语句

    · while语句

· 函数

    · 函数定义

    · 空函数

    · 参数检查

    · 默认参数

    · 可变参数

    · 关键字参数

    · 参数组合

    · 多个返回值

    · 数据类型转换函数

    · 递归函数

· 高级特性

    · 切片

    · 迭代

    · 列表生成式

    · 生成器

· 函数式编程

    · 高阶函数

    · map/reduce

    · filter

    · sorted

    · 返回函数

    · 匿名函数

    · 装饰器

    · 偏函数

· 模块

    · 创建模块

    · 使用模块

    · 安装第三方模块

· 面向对象编程

    · 类与实例

    · 继承与多态

    · 获取对象信息

    · 绑定属性与方法

    · 多重继承

    · 定制类

    · 动态创建类

· 错误、调试和测试

    · 错误处理

    · 调试

    · 单元测试

    · 文档测试

· IO编程

    · 标准输出

    · 标准输入

    · 读文件

    · 写文件

    · 操作文件和目录

    · Python序列化与反序列化

    · JSON序列化与反序列化

· 常用内建模块

    · collections


 

概况

1. 特点:

    a) 优雅、明确、简单。

    b) 跨平台。

    c) 2.x版与3.x版不兼容。

2. 缺点

    a) 解释性语言,与C程序相比运行速度慢。

    b) 代码不能加密。

3. Python解释器

    a) CPython:官方版本解释器;使用最广的解释器;使用C语言开发。

    b) IPython:基于CPython的交互式解释器,即仅交互增强,执行的Python代码功能一样。

    c) PyPy:采用JIT技术,动态编译(非解释执行),执行速度快;与CPython的Python代码小部分不同。

    d) Jython:运行在Java平台上的解释器,将Python代码编译成Java字节码执行。

    e) IronPython:运行在.NET平台上的解释器,将Python代码编译成.NET字节码执行。

安装

1. Python环境搭建:略。

2. 执行方式

    a) 交互式

    b) py文件(python命令)

    c) py文件(直接执行,仅限Linux和Mac)

基础

基础语法

1. 注释:“#”开头。

2. 标识符:

    a) 首字符必须是字母或下划线;

    b) 非首字符可以是字母、数字或下划线;

    c) 大小写敏感。

3. 缩进:未规定几个空格或Tab,按约定俗成,使用4个空格。

数据类型

1. 整型

    a) 范围:任意大小的整数。

    b) 十六进制:用0x前缀和0-9、a-f表示。

    c) 示例:1、100、-8080、0、0xff00、0xa5b4c3d2。

2. 浮点型

    a) 科学计数法:用e表示10。

    b) 示例:1.23、3.14、-9.01、12.3e8、1.2e-5。

3. 字符串

    a) 范围:以“''”或“""”括起来的任意文本。

    b) 转义:转义字符“\”,如\n、\t、\\。

    c) r:表示字符串不转义。

    d) ''':如果字符串含很多换行,使用\n不便阅读,可使用'''化简。

    e) 示例

>>> print('I\'m "OK"!')
I'm "OK"!
>>> print("I'm \"OK\"!")
I'm "OK"!
>>> print('\\\t\\')
\    \
>>> print(r'\\\t\\'
\\\t\\
>>> print('''line1
... line2
... line3''')
line1
line2
line3
View Code

4. 布尔值

    a) 注意大小写:True、False。

    b) 运算符:and、or、not。

5. 空值:None。

变量

以下代码Python解释器做了两件事:

str = 'ABC'

1. 在内存中创建了一个'ABC'的字符串;

2. 在内存中创建了一个名为str的变量,并把它指向'ABC'。

常量

1. 常量:常量仍是变量,Python无任何机制保证常量不被修改。

2. 约定:常量名全部大写。

3. 示例

PI = 3.14159265359

字符编码

1. 默认编码:ASCII(Python诞生比Unicode发布时间早)。

2. UTF-8支持:源文件开头加上。

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

3. u:表示字符串使用Unicode编码。

>>> print('中文')
中文
>>> '中文'
'中文'
View Code

4. ord函数

    a) 声明

ord(c)

    b) 官方说明:Given a string representing one Unicode character, return an integer representing the Unicode code point of that character.

    c) 示例

>>> ord('A')
65
>>> ord('')
20013
View Code

5. chr函数

    a) 声明

chr(i)

    b) 官方说明:Return the string representing a character whose Unicode code point is the integer i.

    c) 示例

>>> chr(65)
'A'
>>> chr(20013)
''
View Code

6. 编码间转换

    a) Unicode编码←→UTF-8编码

>>> 'ABC'.encode('utf-8')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
View Code

    b) Unicode编码←→GB2312编码

>>> '中文'.encode('gb2312')
b'\xd6\xd0\xce\xc4'
>>> b'\xd6\xd0\xce\xc4'.decode('gb2312')
'中文'
View Code

7. len函数

    a) 声明

len(s)

    b) 官方说明:Return the length (the number of items) of an object. The argument may be a sequence (such as a string, bytes, tuple, list, or range) or a collection (such as a dictionary, set, or frozen set).

    c) 额外说明:len函数实际调用对象的__len__方法,自定义类可定义该方法,从而使用len函数获取长度。

    d) 示例

>>> len('ABC')
3
>>> len('中文')
2
>>> class Bird(object):
...     def __len__(self):
...         return 10
...
>>> b = Bird()
>>> len(b)
10
View Code

字符串格式化

1. %运算符:格式化字符串。

2. 占位符

占位符

类型

%d

整数

%f

浮点数

%s

字符串及任意类型

%x

十六进制整数

3. 示例:整数前补空格或0

>>> '%2d-%02d' % (3, 1)
' 3-01'
View Code

4. 示例:指定浮点数小数位数

>>> '%.2f' % 3.1415926
'3.14'
View Code

5. 示例:%s支持任意类型

>>> 'Age: %s. Gender: %s' % (25, True)
'Age: 25. Gender: True'
View Code

6. 示例:%%表示一个%

>>> 'growth rate: %d %%' % 7
'growth rate: 7 %'
View Code

list

1. list:有序集合;元素类型可不同。

2. 索引

    a) 从0开始。

    b) -1表示最后1个元素,-2表示倒数第2个元素。

    c) 索引越界报错:IndexError: list index out of range。

3. len(list)函数:获取元素个数。

4. list.append(element)函数:末尾追加元素。

5. list.insert(index, element)函数:指定索引位置插入元素。

6. list.pop(index)函数:删除元素,index默认为-1。

7. list[index] = element:索引位置替换为另一元素。

8. 示例

>>> classmates = ['Michael', 'Bob', 'Tracy']
>>> classmates[0]
'Michael'
>>> classmates[1]
'Bob'
>>> classmates[-1]
'Tracy'
>>> classmates[-2]
'Bob'
>>> len(classmates)
3
>>> classmates.append('Adam')
>>> classmates
['Michael', 'Bob', 'Tracy', 'Adam']
>>> classmates.insert(1, 'Jack')
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']
>>> classmates.pop()
'Adam'
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy']
>>> classmates.pop(1)
'Jack'
>>> classmates
['Michael', 'Bob', 'Tracy']
>>> classmates[1] = 'Sarah'
>>> classmates
['Michael', 'Sarah', 'Tracy']
>>> list0 = ['Apple', 123, True]
>>> list1 = ['python', 'java', ['asp', 'php'], 'scheme']
>>> len(list1)
4
View Code

9. range函数

    a) 声明

range(stop)
range(start, stop[, step])

    b) 官方说明:This is a versatile function to create lists containing arithmetic progressions. It is most often used in for loops. The arguments must be plain integers. If the step argument is omitted, it defaults to 1. If the start argument is omitted, it defaults to 0. The full form returns a list of plain integers [start, start + step, start + 2 * step, ...]. If step is positive, the last element is the largest start + i * step less than stop; if step is negative, the last element is the smallest start + i * step greater than stop. step must not be zero (or else ValueError is raised).

    c) 示例

>>> [x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [x for x in range(1, 11)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> [x for x in range(0, 30, 5)]
[0, 5, 10, 15, 20, 25]
>>> [x for x in range(0, 10, 3)]
[0, 3, 6, 9]
>>> [x for x in range(0, -10, -1)]
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> [x for x in range(0)]
[]
>>> [x for x in range(1, 0)]
[]
View Code

tuple

1. tuple:与list非常类似,但是tuple一旦初始化就不能修改。

2. 函数:除无修改相关的函数外,其他与list一致。

3. 空tuple:用()表示。

4. 1个元素的tuple(特别注意)

    a) (element, ):1个元素的tuple。

    b) (element):element本身。由于括号()既可以表示tuple,又可以表示括号运算符,为避免歧义,Python规定这种情况下,括号()为运算符。

5. 示例

>>> tuple = ('Michael', 'Bob', 'Tracy')
>>> len(tuple)
3
>>> tuple[0]
'Michael'
>>> tuple[-1]
'Tracy'
>>> tuple0 = ()
>>> tuple0
()
>>> string0 = ('Python')
>>> string0
'Python'
>>> tuple1 = ('Python', )
>>> tuple1
('Python',)
>>> tuple3 = ('a', 'b', ['A', 'B'])
>>> tuple3[2][0] = 'X'
>>> tuple3[2][1] = 'Y'
>>> tuple3
('a', 'b', ['X', 'Y'])
View Code

dict

1. dict:与Java的Map类似,使用key-value存储,具有极快的查找速度;内部存储顺序与key添加顺序无关;key必须是不可变对象。

2. dict[key]:获取value;如果key不存在,则报错KeyError。

3. dict.get(key, default_value)函数:获取value;如果key不存在,则返回None或指定的默认值。

4. dict[key] = value:添加key-value或覆盖key-value。

5. key in dict:如果dict存在key,则返回True,否则返回False。

6. dict.pop(key)函数:删除key-value。

7. 与list相比,dict特点:

    a) 查找和插入的速度极快,不会随着key的增加而增加;

    b) 需要占用大量的内存,内存浪费多。

8. 示例

>>> scores = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> scores0 = dict(Michael=95, Bob=75, Tracy=85)
>>> scores1 = dict([('Michael', 95), ('Bob', 75), ('Tracy', 85)])
>>> scores2 = dict({'Michael': 95, 'Bob': 75, 'Tracy': 85})
>>> scores == scores0 == scores1 == scores2
True
>>> scores['Adam'] = 67
>>> scores['Adam']
67
>>> scores['Adam'] = 88
>>> scores['Adam']
88
>>> scores['Thomas']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Thomas'
>>> 'Thomas' in scores
False
>>> scores.get('Thomas')
>>> scores.get('Thomas', -1)
-1
>>> scores.pop('Bob')
75
>>> scores
{'Michael': 95, 'Tracy': 85, 'Adam': 88}
>>> dict0 = {}
>>> dict0[(1, 2)] = 1
>>> dict0[(1, [2, 3])] = 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
View Code

set

1. set:与dict类似,但不存储value;由于key不允许重复,所以set无重复key。

2. set.add(element)函数:添加元素;如果是重复元素,则无效果。

3. set.remove(element)函数:删除元素。

4. set0 | set1:并集。

5. set0 & set1:交集。

6. set0 - set1:差集。

7. 示例

>>> s = set([1, 1, 2, 2, 3])
>>> s
set([1, 2, 3])
>>> s.add(4)
>>> s
set([1, 2, 3, 4])
>>> s.add(4)
>>> s
set([1, 2, 3, 4])
>>> s.remove(4)
>>> s
set([1, 2, 3])
>>> set0 = set([1, 2, 3])
>>> set1 = set([2, 3, 4])
>>> set0 & set1
set([2, 3])
>>> set0 | set1
set([1, 2, 3, 4])
>>> set0 - set1
set([1])
View Code

if语句

1. 完整if语句模板

if <条件判断1>:
    <执行1>
elif <条件判断2>:
    <执行2>
elif <条件判断3>:
    <执行3>
else:
    <执行4>

2. 执行过程:当条件判断为True、非零数值、非空字符串、非空list等时,即执行。

3. 示例

>>> age = 3
>>> if age >= 18:
...     print('adult')
... elif age >= 6:
...     print('teenager')
... else:
...     print('kid')
... 
kid

for语句

1. 完整for语句模板

for <元素> in <循环对象>:
    <执行1>
else:
    <执行2>

2. 执行过程:循环对象须为collections模块的Iterable类型(含next()函数),for语句不断调用循环对象的next()函数取出元素并执行执行1,直到next()函数raise StopIteration或执行1遇到break语句为止;如果由于next()函数raise StopIteration而终止循环,则执行执行2,否则不执行。

3. break和continue语句:与Java一致。

4. 示例

>>> for n in [1, 2, 3, 4, 5]:
...     print(n)
... else:
...     print('StopIteration')
... 
1
2
3
4
5
StopIteration
>>> for n in [1, 2, 3, 4, 5]:
...     print(n)
...     if n > 3:
...         break
... else:
...     print('StopIteration')
... 
1
2
3
4
>>> sum = 0
>>> for n in range(101):
...     sum += n
... 
>>> print(sum)
5050
>>> for ch in 'ABC':
...     print(ch)
... 
A
B
C
View Code

while语句

1. 完整while语句模板

while<条件判断>:
    <执行1>
else:
    <执行2>

2. 执行过程:如果条件判断为True、非零数值、非空字符串、非空list等,则不断执行执行1,直到条件判断不成立或遇到break语句为止;如果由于条件判断不成立而终止循环,则执行执行2,否则不执行。

3. break和continue语句:与Java一致。

4. 示例

>>> sum = 0
>>> n = 1
>>> while n < 101:
...     sum += n
...     n += 1
...
>>> print(sum)
5050
View Code

函数

函数定义

1. 函数定义模板

def <函数名>(<函数参数>):
    <函数体>

2. 返回值

    a) 如果没有return语句,函数执行完毕后返回None。

    b) return None简写为return

3. 示例

>>> def my_abs(x):
...     if x >= 0:
...         return x
...     else:
...         return -x
... 
>>> my_abs(100)
100
View Code

空函数

1. 空函数:什么都不做的函数。

2. 空函数模板

def <函数名>(<函数参数>):
    pass

3. pass语句

    a) 用途:占位符,避免语法错误。

    b) 示例(除空函数外)

>>> age = 20
>>> if age >= 18:
...     pass
View Code

参数检查

1. 参数个数检查:Python解释器自动检查,如果不对,则报错TypeError。

>>> my_abs(1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: my_abs() takes 1 positional argument but 2 were given
View Code

2. 参数类型检查:自行检查。

>>> my_abs('A')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in my_abs
TypeError: '>=' not supported between instances of 'str' and 'int'
>>> def my_abs(x):
...     if not isinstance(x, (int, float)):
...         raise TypeError('bad operand type')
...     if x >= 0:
...         return x
...     else:
...         return -x
...
>>> my_abs('A')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in my_abs
TypeError: bad operand type
View Code

3. isinstance函数

    a) 声明

isinstance(object, classinfo)

    b) 官方说明:Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof. If object is not an object of the given type, the function always returns false. If classinfo is a tuple of type objects (or recursively, other such tuples), return true if object is an instance of any of the types. If classinfo is not a type or tuple of types and such tuples, a TypeError exception is raised.

    c) 示例

>>> obj = True
>>> isinstance(obj, int)
True
>>> isinstance(obj, bool)
True
>>> obj = 10
>>> isinstance(obj, int)
True
>>> isinstance(obj, bool)
False
View Code

默认参数

1. 用途:简化函数调用。

2. 参数顺序:必选参数在前,默认参数在后,否则Python的解释器会报错。

3. 示例

>>> def enroll(name, gender, age=6, city='Beijing'):
...     print('name = %s, gender = %s, age = %d, city = %s' % (name, gender, age, city))
...
>>> enroll('Sarah', 'F')
name = Sarah, gender = F, age = 6, city = Beijing
>>> enroll('Bob', 'M', 7)
name = Bob, gender = M, age = 7, city = Beijing
>>> enroll('Adam', 'M', city='Tianjin')
name = Adam, gender = M, age = 6, city = Tianjin
>>> enroll('Jhon', 'F', city='Tianjin', age=7)
name = Jhon, gender = F, age = 7, city = Tianjin
View Code

4. 注意:默认参数必须指向不变对象。因为函数定义时默认参数已被初始化,调用函数时,如果默认参数指向的对象改变,则会影响下次调用。

    a) 错误用法

>>> def add_end(l=[]):
...     l.append('END')
...     return l
... 
>>> add_end([1, 2, 3])
[1, 2, 3, 'END']
>>> add_end(['x', 'y', 'z'])
['x', 'y', 'z', 'END']
>>> add_end()
['END']
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
View Code

    b) 正确用法

>>> def add_end(l=None):
...     if l is None:
...         l = []
...     l.append('END')
...     return l
... 
>>> add_end()
['END']
>>> add_end()
['END']
View Code

可变参数

1. 可变参数:传入参数个数为任意个(包括0个),在参数前加*号表示。

2. 本质:传入的可变参数被自动组装成一个tuple。

3. 将list或tuple的元素当成可变参数传入:参数前加*号。

4. 示例

>>> def sum(*numbers):
...     sum = 0
...     for n in numbers:
...         sum += n
...     return sum
... 
>>> sum(1, 2, 3)
6
>>> l = [1, 2, 3]
>>> sum(*l)
6
>>> sum()
0
View Code

关键字参数

1. 关键字参数:传入参数个数为任意个(包括0个),在参数前加**号表示。

2. 本质:传入的关键字参数被自动组装成一个dict。

3. 将dict的key-value当成关键字参数传入:参数前加**号。

4. 示例

>>> def person(name, age, **others):
...     print('name =', name, 'age =', age, 'others =', others)
...
>>> person('Michael', 30)
name = Michael age = 30 others = {}
>>> person('Bob', 35, city='Beijing')
name = Bob age = 35 others = {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name = Adam age = 45 others = {'gender': 'M', 'job': 'Engineer'}
>>> kw = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **kw)
name = Jack age = 24 others = {'city': 'Beijing', 'job': 'Engineer'}
View Code

参数组合

1. 参数顺序:必选参数、默认参数、可变参数、关键字参数。

2. 万能参数:(*args, **kw),可接收任意参数。

3. 示例

>>> def func(a, b, c=0, *args, **kw):
...     print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
...
>>> func(1, 2)
a = 1 b = 2 c = 0 args = () kw = {}
>>> func(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> func(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
>>> func(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
>>> args = (1, 2, 3, 4)
>>> kw = {'x': 99}
>>> func(*args, **kw)
a = 1 b = 2 c = 3 args = (4,) kw = {'x': 99}
View Code

多个返回值

1. 本质:多个返回值的本质是返回一个tuple;返回一个tuple可省略括号,同时可使用多个变量接受一个tuple。

2. 示例

>>> def test_fn():
...     return 1, 'A'
...
>>> x, y = test_fn()
>>> print(x, y)
1 A
>>> z = test_fn()
>>> z
(1, 'A')
View Code

数据类型转换函数

1. int函数

    a) 声明

class int(x=0)
class int(x, base=10)

    b) 官方说明:Return an integer object constructed from a number or string x, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating point numbers, this truncates towards zero. If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in radix base. Optionally, the literal can be preceded by + or - (with no space in between) and surrounded by whitespace. A base-n literal consists of the digits 0 to n-1, with a to z (or A to Z) having values 10 to 35. The default base is 10. The allowed values are 0 and 2–36. Base-2, -8, and -16 literals can be optionally prefixed with 0b/0B, 0o/0O, or 0x/0X, as with integer literals in code. Base 0 means to interpret exactly as a code literal, so that the actual base is 2, 8, 10, or 16, and so that int('010', 0) is not legal, while int('010') is, as well as int('010', 8).

    c) 示例

>>> int('123')
123
>>> int(12.34)
12
View Code

2. float函数

    a) 声明

class float([x])

    b) 官方说明:Return a floating point number constructed from a number or string x.

    c) 示例

>>> float('12.34')
12.34
View Code

3. bool函数

    a) 声明

class bool([x])

    b) 官方说明:Return a Boolean value, i.e. one of True or False. x is converted using the standard truth testing procedure. If x is false or omitted, this returns False; otherwise it returns True.

    c) 示例

>>> bool(1)
True
>>> bool('')
False
View Code

4. str函数

    a) 声明

class str(object='')

    b) 官方说明:
Return a string version of object. If object is not provided, returns the empty string. Otherwise, the behavior of str() depends on whether encoding or errors is given, as follows.

If neither encoding nor errors is given, str(object) returns object.__str__(), which is the “informal” or nicely printable string representation of object. For string objects, this is the string itself. If object does not have a __str__() method, then str() falls back to returning repr(object).

If at least one of encoding or errors is given, object should be a bytes-like object (e.g. bytes or bytearray). In this case, if object is a bytes (or bytearray) object, then str(bytes, encoding, errors) is equivalent to bytes.decode(encoding, errors). Otherwise, the bytes object underlying the buffer object is obtained before calling bytes.decode(). See Binary Sequence Types — bytes, bytearray, memoryview and Buffer Protocol for information on buffer objects.

    c) 示例

>>> str(1.23)
'1.23'
View Code

递归函数

1. 示例

>>> def sum(begin, end):
...     if begin >= end:
...         return end
...     return begin + sum(begin + 1, end)
...
>>> sum(1, 100)
5050
View Code

2. 注意:递归调用次数过多,导致栈溢出(Python未实现尾递归优化)

>>> sum(1, 1000000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in sum
  File "<stdin>", line 4, in sum
  File "<stdin>", line 4, in sum
  [Previous line repeated 994 more times]
  File "<stdin>", line 2, in sum
RecursionError: maximum recursion depth exceeded in comparison
View Code

高级特性

切片

1. 切片:按照一定规则从list、tuple或字符串取出元素,并生成新list、tuple或字符串。

2. lt[:]:取出索引begin至end-1的元素。

3. lt[::]:从索引begin开始至end-1,每隔step个索引取出一个元素。

4. 简写

    a) 如果省略begin,则begin为0。

    b) 如果省略end,则end为len(lt)。

    c) 如果同时省略begin和end,则表示复制lt。

5. 示例

>>> names = ['Michael', 'Sarah', 'Tracy']
>>> names[0:3]
['Michael', 'Sarah', 'Tracy']
>>> names[:3]
['Michael', 'Sarah', 'Tracy']
>>> names[1:3]
['Sarah', 'Tracy']
>>> names[-2:]
['Sarah', 'Tracy']
>>> names[-2:-1]
['Sarah']
>>> names[:]
['Michael', 'Sarah', 'Tracy']
>>> l = range(100)
>>> [x for x in l[:10]]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [x for x in l[-10:]]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> [x for x in l[10:20]]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> [x for x in l[:10:2]]
[0, 2, 4, 6, 8]
>>> [x for x in l[::5]]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[::2]
'ACEG'
View Code

迭代

1. enumerate函数(得到迭代元素及其索引)

    a) 声明

enumerate(sequence, start=0)

    b) 官方说明:Return an enumerate object. iterable must be a sequence, an iterator, or some other object which supports iteration. The __next__() method of the iterator returned by enumerate() returns a tuple containing a count (from start which defaults to 0) and the values obtained from iterating over iterable.

    c) 示例

>>> for index, value in enumerate(['A', 'B', 'C']):
...     print(index, value)
...
0 A
1 B
2 C
View Code

2. 示例:迭代元素是tuple的list

>>> for x, y in [(1, 1), (2, 4), (3, 9)]:
...     print(x, y)
...
1 1
2 4
3 9
View Code

3. 示例:迭代dict(共4种方法,性能:第1种最好,第2种略差,第3、4种最差)

>>> scores = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> for key in scores:
...     print(key, scores[key])
...
Michael 95
Bob 75
Tracy 85
>>> for key, value in scores.items():
...     print(key, value)
...
Michael 95
Bob 75
Tracy 85
>>> for key, value in zip(scores.keys(), scores.values()):
...     print(key, value)
...
Michael 95
Bob 75
Tracy 85
View Code

列表生成式

1. 列表生成式:List Comprehensions。

2. 列表生成式模板

    a) 模板1:遍历对象循环(支持嵌套循环)中的元素,得到新元素,最后生成list。

[<新元素表达式> for <元素0> in <循环对象0> for <元素1> in <循环对象1> ...]

    b) 模板2:仅当满足条件时,才计算新元素生成list。

[<新元素表达式> for <元素0> in <循环对象0> for <元素1> in <循环对象1> ... if <条件判断>]

3. 示例

>>> [n * n for n in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> [n * n for n in range(1, 11) if n % 2 == 0]
[4, 16, 36, 64, 100]
>>> [m + n for m in 'ABCD' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ', 'DX', 'DY', 'DZ']
>>> [m + n for m in 'ABCD' for n in 'XYZ' if m > 'B' and n > 'X']
['CY', 'CZ', 'DY', 'DZ']
View Code

生成器

1. 与列表生成式区别:列表生成式存储的是元素,占用内存较大;生成器(generator)存储的是元素生成算法,占用内存较小。

2. 生成器模板

    a) 模板1:与列表生成器模板1和2一致,只是将[]改为();适用于简单逻辑。

    b) 模板2:定义函数,在函数体内通过yield语句返回元素;适用于复杂逻辑。

3. 迭代方法:一般通过for语句调用生成器的next()函数获取元素进行迭代。

4. 示例

>>> g1 = (n * n for n in range(1, 11))
>>> for n in g1:
...     print(n)
...
1
4
9
16
25
36
49
64
81
100
>>> def gen():
...     for n in range(1, 11):
...         yield n * n
...
>>> g2 = gen()
>>> for n in g2:
...     print(n)
...
1
4
9
16
25
36
49
64
81
100
View Code

函数式编程

高阶函数

1. 高阶函数:将函数作为参数传入的函数。

2. 本质

    a) 变量可指向函数。

>>> abs
<built-in function abs>
>>> abs(-10)
10
>>> f = abs
>>> f(-10)
10
>>> f
<built-in function abs>
View Code

    b) 函数名也是变量名。

>>> abs = 'ABC'
>>> abs(-10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
View Code

3. 示例

>>> def add(m, n, f):
...     return f(m) + f(n)
... 
>>> add(-5, 6, abs)
11
View Code

map/reduce

1. map函数

    a) 声明

map(function, iterable, …)

    b) 官方说明:Return an iterator that applies function to every item of iterable, yielding the results. If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel. With multiple iterables, the iterator stops when the shortest iterable is exhausted. For cases where the function inputs are already arranged into argument tuples, see itertools.starmap().

    c) 示例

>>> def f(x):
...     return x * x
...
>>> [x for x in map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])]
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [x for x in map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])]
['1', '2', '3', '4', '5', '6', '7', '8', '9']

2. reduce函数

    a) 声明

functools.reduce(function, iterable[, initializer])

    b) 官方说明:Apply function of two arguments cumulatively to the items of sequence, from left to right, so as to reduce the sequence to a single value.

    c) 示例

>>> from functools import reduce
>>> reduce(add, [1, 3, 5, 7, 9])
25
>>> reduce(lambda x, y: x + y, [1, 3, 5, 7, 9])
25
View Code

filter

1. 声明

filter(function, iterable)

2. 官方说明:Construct an iterator from those elements of iterable for which function returns true. iterable may be either a sequence, a container which supports iteration, or an iterator. If function is None, the identity function is assumed, that is, all elements of iterable that are false are removed.

3. 示例

>>> def is_odd(n):
...     return n % 2 == 1
...
>>> [x for x in filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])]
[1, 5, 9, 15]
View Code

sorted

1. 声明

sorted(iterable, *, key=None, reverse=False)

2. 官方说明:Return a new sorted list from the items in iterable.

3. 示例

>>> sorted([36, 5, 12, 9, 21])
[5, 9, 12, 21, 36]
>>> sorted([36, 5, 12, 9, 21], reverse=True)
[36, 21, 12, 9, 5]
View Code

返回函数

1. 返回函数:高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

2. 返回函数注意:每次调用返回函数的函数,都会返回一个新函数。

3. 闭包(closure):简单理解是,能够读取其他函数内部变量的函数。

4. 闭包注意:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

5. 示例:一般方式与闭包方式

>>> def calc_sum(numbers):
...     s = 0
...     for n in numbers:
...         s += n
...     return s
... 
>>> calc_sum(range(1, 101))
5050
View Code
>>> def lazy_sum(numbers):
...     def sum():
...         s = 0
...         for n in numbers:
...             s += n
...         return s
...     return sum
...
>>> f = lazy_sum(range(1, 101))
>>> f
<function lazy_sum.<locals>.sum at 0x00000084C154E268>
>>> f()
5050
>>> f1 = lazy_sum(range(1, 101))
>>> f == f1
False
View Code

6. 示例:闭包陷阱与陷阱规避

>>> def count():
...     fs = []
...     for i in range(1, 4):
...         def f():
...             return i * i
...         fs.append(f)
...     return fs
... 
>>> f1, f2, f3 = count()
>>> f1()
9
>>> f2()
9
>>> f3()
9
View Code
>>> def count():
...     fs = []
...     for i in range(1, 4):
...         def f(j):
...             def g():
...                 return j * j
...             return g
...         fs.append(f(i))
...     return fs
... 
>>> f1, f2, f3 = count()
>>> f1()
1
>>> f2()
4
>>> f3()
9
View Code

匿名函数

1. 定义方法:lambda关键字,冒号前的标识符为函数参数,无须return语句,表达式就是返回值。

2. 使用方法:

    a) 作为函数参数传入;

    b) 赋值给变量;

    c) 作为函数返回值。

3. 示例

>>> [x for x in map(lambda n: n * n, range(1, 11))]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> f = lambda x, y: x + y
>>> f(1, 2)
3
>>> def calc_sum(x, y):
...     return lambda: x + y
...
View Code

装饰器

1. 装饰器:Python除了能支持OOP的decorator外,直接从语法层次支持decorator。

2. f.__name__属性:每个函数都有该存储函数名的属性。

3. 装饰器(Decorator):在不修改某函数代码的情况下,在执行该函数时动态增加新的功能。

4. 示例:无函数参数的装饰器

 1 # -*- coding: utf-8 -*-
 2 import time
 3 import functools
 4 def log(func):
 5     @functools.wraps(func) # 保证now.__name__为now
 6     def wrapper(*args, **kw):
 7         print('begin %s()' % func.__name__)
 8         ret = func(*args, **kw)
 9         print('end %s()' % func.__name__)
10         return ret
11     return wrapper
12 @log
13 def now():
14     print(time.time())
15 # 相当于执行log(now)
16 now()
17 print(now.__name__)
View Code
python decorator0.py
begin now()
1517555102.5761998
end now()
now

5. 示例:有函数参数的装饰器

 1 # -*- coding: utf-8 -*-
 2 import time
 3 import functools
 4 def log(text):
 5     def decorator(func):
 6         @functools.wraps(func) # 保证now.__name__为now
 7         def wrapper(*args, **kw):
 8             print('begin %s %s()' % (text, func.__name__))
 9             ret = func(*args, **kw)
10             print('end %s %s()' % (text, func.__name__))
11             return ret
12         return wrapper
13     return decorator
14 @log('testarg')
15 def now():
16     print(time.time())
17 # 相当于执行log('testarg')(now)
18 now()
19 print(now.__name__)
View Code
python decorator1.py
begin testarg now()
1517555185.114952
end testarg now()
now

偏函数

functools.partial函数

    a) 声明

functools.partial(func[,*args][, **keywords])

    b) 官方说明:Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments keywords. If more arguments are supplied to the call, they are appended to args. If additional keyword arguments are supplied, they extend and override keywords.

    c) 说明:把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

    d) 示例

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85
View Code

模块

创建模块

1. 模块(Module):一个.py文件就称之为一个模块。

2. 包(Package):按目录来组织模块的方法,多级目录可组成多级层次的包结构。

3. __init__.py文件

    a) 每一个包目录下必须有一个__init__.py的文件,否则,Python把这个目录当成普通目录;

    b) __init__.py可以是空文件,也可以有Python代码。

    c) __init__.py本身也是一个模块,模块名即是其包名。

    d) 引入模块时,将从顶层包开始一级级执行__init__.py文件中的代码。

4. 好处

    a) 提高代码可维护性。

    b) 编写代码不必从零开始,当一个模块编写完毕,就可以被其他地方引用。

    c) 避免函数名和变量名冲突。但是也要注意,尽量不要与内置函数名字冲突。

5. 内置函数

abs()

dict()

help()

min()

setattr()

all()

dir()

hex()

next()

slice()

any()

divmod()

id()

object()

sorted()

ascii()

enumerate()

input()

oct()

staticmethod()

bin()

eval()

int()

open()

str()

bool()

exec()

isinstance()

ord()

sum()

bytearray()

filter()

issubclass()

pow()

super()

bytes()

float()

iter()

print()

tuple()

callable()

format()

len()

property()

type()

chr()

frozenset()

list()

range()

vars()

classmethod()

getattr()

locals()

repr()

zip()

compile()

globals()

map()

reversed()

__import__()

complex()

hasattr()

max()

round()

 

delattr()

hash()

memoryview()

set()

 

6. 示例:

目录

类型

名称

mycompany/

├── abc.py

├── __init__.py

├── utils.py

├── web

│   ├── __init__.py

│   ├── utils.py

│   └── www.py

└── xyz.py

模块

模块

模块

模块

模块

模块

模块

mycompany

mycompany.abc

mycompany

mycompany.utils

mycompany.web

mycompany.web

mycompany.web.utils

mycompany.web.www

mycompany.xyz

使用模块

1. 文件示例:hello.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
' 文档注释 '
__author__ = '作者'

import sys
def test():
    args = sys.argv
    if len(args) == 1:
        print('Hello, world!')
    elif len(args) == 2:
        print('Hello, %s!' % args[1])
    else:
        print('Too many arguments!')

if __name__ == '__main__':
    test()
View Code

    a) 文档注释:任何模块代码的第一个字符串都被视为模块的文档注释。

    b) 前4行是标准文件模板,但也可以全部不写。

    c) import sys:导入sys模块后,就有了指向该模块的变量sys,可以访问sys模块的所有功能。

    d) sys.argv变量:用list存储了命令行的所有参数。第1个参数永远是该.py文件名。

    e) __name__变量:如果在命令行运行hello模块,则值为'__main__';如果引入hello模块,则值为其他值。

2. 模块别名:通过“import <模块名> as <别名>”方式为引入的模块起别名,即可通过别名访问模块功能。

3. 可见性

    a) 正常函数和变量是public,可被直接引用。

    b) 类似__xxx__变量是特殊变量(如__author__、__name__、__doc__),可被直接引用,自己的变量一般不要用这种变量名。

    c) 类似_xxx和__xxx函数或变量是private,不应被直接引用。注意:Python并没有一种方法可以完全限制访问private函数或变量,但是从编程习惯上不应引用。

安装第三方模块

1. 工具

    a) Anaconda,支持Windows、macOS和Linux。

    b) pip。

2. 模块搜索路径

    a) 默认搜索:当前目录、所有已安装的内置模块和第三方模块。

    b) 查看搜索路径:

>>> import sys
>>> sys.path
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/usr/lib/python3.5/lib-dynload', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']
View Code

    c) 修改搜索路径方法1:直接修改sys.path,运行结束后失效。

>>> import sys
>>> sys.path.append('/home/netoxi/workspace/testpy')
View Code

    d) 修改搜索路径方法2:设置环境变量PYTHONPATH。

面向对象编程

类与实例

1. Python对象

    a) 所有数据类型都可视为对象。

    b) 根类:所有类最终都会继承object类。

2. 类声明模板

class <类名>(<父类名>):
    pass

3. 构造方法:__init__方法(只能有1个);第1个参数永远是self(类似Java的this),其由Python解释器传入。

4. 类创建模板

<变量名> = <类名>(<方法参数>)

5. 类中的方法:与普通函数只有一点区别,即第1个参数永远是self,其由Python解释器传入。

6. private属性:属性名前加两个下划线__,外部不可直接访问。实际上,Python解释器将__<属性名>改为_<类名>__<属性名>,因此仍可通过_<类名>__<属性名>访问(强烈建议不要这样访问,解释器可能会把__<属性名>改成不同的变量名)。

7. _<属性名>属性:一个下划线_开头的实例变量,外部可直接访问,但约定俗成将其视为private属性。

8. 特殊属性:属性名前和后加两个下划线__,外部可直接访问,不是private变量。不要自定义__<属性名>__。

9. @property装饰器:Python内置@property装饰器负责将方法变成属性调用。getter方法变成属性,加上@property;setter方法变成属性,加上@<属性名>.setter。

10. 示例

>>> class Student(object):
...     def __init__(self, name, gender):
...         self.name = name
...         self.__gender = gender
...     @property
...     def score(self):
...         return self._score
...     @score.setter
...     def score(self, value):
...         if not isinstance(value, int):
...             raise ValueError('score must be an integer!')
...         if value < 0 or value > 100:
...             raise ValueError('score must between 0 ~ 100!')
...         self._score = value
...     @property
...     def birth(self):
...         return self._birth
...     @birth.setter
...     def birth(self, value):
...         self._birth = value
...     @property
...     def age(self):
...         return 2014 - self._birth
... 
>>> s = Student('Jhon', 'm')
>>> s.name
'Jhon'
>>> s.name = 'Harry'
>>> s.name
'Harry'
>>> s.__gender
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__gender'
>>> s._Student__gender
'm'
>>> s.score
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in score
AttributeError: 'Student' object has no attribute '_score'
>>> s.score = 101
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 13, in score
ValueError: score must between 0 ~ 100!
>>> s.score = 98
>>> s.score
98
>>> s.birth = 1995
>>> s.age
19
View Code

继承与多态

1. 继承与多态:Python的继承、多态与C++和Java类似。

2. 示例

>>> class Animal(object):
...     def eat(self):
...         print('Animal is eating')
...
>>> class Dog(Animal):
...     def eat(self):
...         print('Dog is eating')
...
>>> class Dog(Animal):
...     def eat(self):
...         print('Dog is eating')
...     def run(self):
...         print('Dog is running')
...
>>> class Fish(Animal):
...     def eat(self):
...         print('Fish is eating')
...     def swim(self):
...         print('Fish is swimming')
...
>>> a = Animal()
>>> d = Dog()
>>> f = Fish()
>>> a.eat()
Animal is eating
>>> d.eat()
Dog is eating
>>> d.run()
Dog is running
>>> f.eat()
Fish is eating
>>> f.swim()
Fish is swimming
>>> isinstance(a, Animal)
True
>>> isinstance(d, Dog)
True
>>> isinstance(f, Fish)
True
>>> isinstance(d, Animal)
True
>>> isinstance(f, Animal)
True
>>> isinstance(a, Dog)
False
>>> isinstance(a, Fish)
False
View Code

获取对象信息

1. type函数

    a) 声明

class type(object)

    b) 官方说明:With one argument, return the type of an object. The return value is a type object. The isinstance() built-in function is recommended for testing the type of an object.

    c) 示例

>>> type(123)
<class 'int'>
>>> type('str')
<class 'str'>
>>> type(isinstance)
<class 'builtin_function_or_method'>
>>> type(123) == type(456)
True
>>> type(123) == int
True
>>> type('abc') == type('123')
True
>>> type('abc') == str
True
>>> type('abc') == type(123)
False
>>> import types
>>> def fn():
...     pass
...
>>> type(fn) == types.FunctionType
True
>>> type(isinstance) == types.BuiltinFunctionType
True
>>> type(lambda x: x) == types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True
View Code

2. isinstance函数(判断继承关系更方便)

    a) 声明

isinstance(object, classinfo)

    b) 官方说明:Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof. If object is not an object of the given type, the function always returns false. If classinfo is a tuple of type objects (or recursively, other such tuples), return true if object is an instance of any of the types. If classinfo is not a type or tuple of types and such tuples, a TypeError exception is raised.

    c) 示例

>>> a = Animal()
>>> d = Dog()
>>> isinstance(d, Animal)
True
>>> isinstance(d, Dog)
True
>>> isinstance('a', str)
True
>>> isinstance(123, int)
True
>>> isinstance(b'a', bytes)
True
>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))
True
View Code

3. dir函数

    a) 声明

dir([object])

    b) 官方说明:Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object. If the object has a method named __dir__(), this method will be called and must return the list of attributes. This allows objects that implement a custom __getattr__() or __getattribute__() function to customize the way dir() reports their attributes. If the object does not provide __dir__(), the function tries its best to gather information from the object’s __dict__ attribute, if defined, and from its type object. The resulting list is not necessarily complete, and may be inaccurate when the object has a custom __getattr__(). The default dir() mechanism behaves differently with different types of objects, as it attempts to produce the most relevant, rather than complete, information:

        i. If the object is a module object, the list contains the names of the module’s attributes.

        ii. If the object is a type or class object, the list contains the names of its attributes, and recursively of the attributes of its bases.

        iii. Otherwise, the list contains the object’s attributes’ names, the names of its class’s attributes, and recursively of the attributes of its class’s base classes.

    c) 示例

>>> dir('ABC')
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
View Code

4. *attr函数

    a) 声明

hasattr(object, name)
getattr(object, name[, default])
setattr(object, name, value)
delattr(object, name)

    b) 官方说明(hasattr):The arguments are an object and a string. The result is True if the string is the name of one of the object’s attributes, False if not. (This is implemented by calling getattr(object, name) and seeing whether it raises an exception or not.)

    c) 官方说明(getattr):Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

    d) 官方说明(setattr):This is the counterpart of getattr(). The arguments are an object, a string and an arbitrary value. The string may name an existing attribute or a new attribute. The function assigns the value to the attribute, provided the object allows it.

    e) 官方说明(delattr):This is a relative of setattr(). The arguments are an object and a string. The string must be the name of one of the object’s attributes. The function deletes the named attribute, provided the object allows it. For example, delattr(x, 'foobar') is equivalent to del x.foobar.

    f) 示例

>>> class MyObject(object):
...     def __init__(self):
...         self.x = 9
...         self.y = 10
...
>>> obj = MyObject()
>>> hasattr(obj, 'x')
True
>>> hasattr(obj, 'z')
False
>>> setattr(obj, 'z', 18)
>>> hasattr(obj, 'z')
True
>>> getattr(obj, 'z')
18
>>> delattr(obj, 'z')
>>> getattr(obj, 'z')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyObject' object has no attribute 'z'
>>> getattr(obj, 'z', 28)
28
View Code

绑定属性与方法

1. 绑定属性与方法

    a) 正常情况下,可为类和实例绑定属性和方法,这就是动态语言的灵活性。

    b) 如果为类的某个实例绑定属性和方法,这些绑定的属性和方法仅对该实例有效,对该类的其他实例无效。

    c) 如果为类绑定属性和方法,则这些绑定的属性和方法对该类的所有实例有效。

2. __slots__属性

    a) 定义类时,限制只能绑定的属性名。

    b) __slots__定义的属性仅对当前类有效,对子类无效;如果子类也定义__slots__,则子类允许绑定的属性名就是自身的__slots__加上父类的__slots__。

3. 示例

>>> class Student(object):
...     pass
...
>>> s = Student()
>>> s.name = 'Michael'
>>> print(s.name)
Michael
>>> def set_age(self, age):
...     self.age = age
...
>>> from types import MethodType
>>> s.set_age = MethodType(set_age, s)
>>> s.set_age(25)
>>> print(s.age)
25
>>> s2 = Student()
>>> s2.set_age(25)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'set_age'
>>> def set_score(self, score):
...     self.score = score
...
>>> Student.set_score = set_score
>>> s.set_score(100)
>>> print(s.score)
100
>>> s2.set_score(99)
>>> print(s2.score)
99
View Code
>>> class Student(object):
...     __slots__ = ('name', )
...
>>> s = Student()
>>> s.name = 'Jhon'
>>> s.age = 22
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'age'
View Code

多重继承

1. 多重继承:通过多重继承,一个子类可以同时获得多个父类的所有功能。

2. Mixin设计

    a) 思路:在设计类的继承关系时,通常主线都是单一继承下来,如果需要“混入”额外功能,通过多重继承实现。

    b) 优先考虑通过多重继承来组合多个Mixin的功能,而不是设计多层次的复杂的继承关系。

3. 示例

 1 class Animal(object):
 2     pass
 3 # 大类:
 4 class Mammal(Animal):
 5     pass
 6 class Bird(Animal):
 7     pass
 8 # 功能
 9 class RunnableMixin(object):
10     def run(self):
11         print('Running...')
12 class FlyableMixin(object):
13     def fly(self):
14         print('Flying...')
15 # 各种动物:
16 class Dog(Mammal, RunnableMixin):
17     pass
18 class Bat(Mammal, FlyableMixin):
19     pass
20 class Parrot(Bird, FlyableMixin):
21     pass
22 class Ostrich(Bird, RunnableMixin):
23     pass
View Code

定制类

1. __str__方法

    a) 用途:使用print语句打印时被调用,一般供用户查看。

    b) __repr__方法:命令行打印时被调用,一般供开发者调试。

    c) 示例

>>> class Student(object):
...     def __init__(self, name):
...         self.name = name
...     def __str__(self):
...         return 'Student object (name=%s)' % self.name
...     __repr__ = __str__
...
>>> s = Student('Michael')
>>> print(s)
Student object (name=Michael)
>>> s
Student object (name=Michael)
View Code

2. __iter__方法

    a) 用途:对象可使用for语句循环,for语句不断调用该迭代对象的next()方法拿到循环的下一个值。

    b) 示例

>>> class Fib(object):
...     def __init__(self):
...         self.a, self.b = 0, 1 # 初始化两个计数器a,b
...     def __iter__(self):
...         return self # 实例本身就是迭代对象,故返回自己
...     def __next__(self):
...         self.a, self.b = self.b, self.a + self.b # 计算下一个值
...         if self.a > 50: # 退出循环的条件
...             raise StopIteration();
...         return self.a # 返回下一个值
...
>>> for n in Fib():
...     print(n)
...
1
1
2
3
5
8
13
21
34
View Code

3. __getitem__方法

    a) 用途:使对象可像list那样通过下标取出元素、切片。

    b) 方法参数:下标取出元素时,方法参数为int;切片时,方法参数为切片对象slice。

    c) 示例

>>> class Fib(object):
...     def __getitem__(self, n):
...         if isinstance(n, int): # n是索引
...             a, b = 1, 1
...             for x in range(n):
...                 a, b = b, a + b
...             return a
...         if isinstance(n, slice): # n是切片
...             start = n.start
...             stop = n.stop
...             if start is None:
...                 start = 0
...             a, b = 1, 1
...             L = []
...             for x in range(stop):
...                 if x >= start:
...                     L.append(a)
...                 a, b = b, a + b
...             return L
...
>>> f = Fib()
>>> f[0]
1
>>> f[100]
573147844013817084101
>>> f[0:5]
[1, 1, 2, 3, 5]
>>> f[:10]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> f[:10:2] # 没有对step参数作处理
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
View Code

4. __getattr__方法

    a) 用途:未找到属性或方法时,调用__getattr__方法获取,实现了属性和方法的动态化。

    b) 示例

>>> class Student(object):
...     def __init__(self, name):
...         self.name = name
...     def __getattr__(self, attr):
...         if attr == 'gender':
...             return 'm'
...         if attr == 'age':
...             return lambda: 2017 - 1995
...         raise AttributeError('\'Student\' object has no attribute \'%s\'' %
attr)
...
>>> s = Student('Jhon')
>>> s.name
'Jhon'
>>> s.gender
'm'
>>> s.age
<function Student.__getattr__.<locals>.<lambda> at 0x000000F258362E18>
>>> s.age()
22
>>> s.score
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in __getattr__
AttributeError: 'Student' object has no attribute 'score'
View Code

5. __call__方法

    a) 用途:当使用<对象名>()调用时,调用__call__方法,即使对象能像函数一样被调用。

    b) 注意:__call__方法使对象和函数界限模糊化,这两类都是Callable对象,可通过callable函数判断。

    c) 示例

>>> class Student(object):
...     def __init__(self, name):
...         self.name = name
...     def __call__(self, another):
...         print('Hello, %s, my name is %s.' % (another, self.name))
...
>>> s = Student('John')
>>> s('Harry')
Hello, Harry, my name is John.
>>> class Teacher(object):
...     pass
...
>>> t = Teacher()
>>> callable(s)
True
>>> callable(t)
False
>>> callable(callable)
True
>>> callable([1, 2, 3])
False
>>> callable(None)
False
>>> callable('abc')
False
View Code

动态创建类

1. type函数

    a) 声明

class type(name, bases, dict)

    b) 官方说明:Return a new type object. This is essentially a dynamic form of the class statement. The name string is the class name and becomes the __name__ attribute; the bases tuple itemizes the base classes and becomes the __bases__ attribute.

    c) 示例

>>> def sayHello(self, another):
...     print("Hello, %s, my name is %s." % (another, self.name))
...
>>> Student = type("Student", (object, ), {"name": "John", "sayHello": sayHello})
>>> s = Student()
>>> s.name
'John'
>>> s.sayHello("Harry")
Hello, Harry, my name is John.
View Code

2. metaclass

    a) 理解:元数据metadata是描述数据的数据,那么metaclass就是描述类的类。可把类看成是metaclass创建出来的“实例”,即先定义metaclass,就可以创建类,最后创建实例。

    b) 示例

>>> # metaclass是类的模板,所以必须从`type`类型派生:
... class ListMetaclass(type):
...     def __new__(cls, name, bases, attrs):
...         attrs['add'] = lambda self, value: self.append(value)
...         return type.__new__(cls, name, bases, attrs)
...
>>> class MyList(list, metaclass=ListMetaclass):
...     pass
...
>>> l = MyList()
>>> l.add(1)
>>> l
[1]
View Code

3. 个人想法:与Java类似,动态创建类应该较多用于编写基础框架,一般开发较少用到。

错误、调试和测试

错误处理

1. try语句

    a) 与Java的try语句类似。

    b) 错误类型:所有错误类型都继承自BaseException,Python内置错误如下。

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
      |    +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

    c) except:当捕获父错误类型时,也会将其子错误类型捕获。因此,except应该优先捕获子错误类型,再捕获父错误类型,否则子错误类型except永远不会捕获。

    d) else:位于最后一个except块之后。当没有错误发生时,会自动执行else。

    e) 自定义错误类型:必要时可自定义错误类型,否则尽量使用内置的错误类型。

    f) 示例

>>> try:
...     print('try...')
...     r = 10 / int('a')
...     print('result:', r)
... except ValueError as e:
...     print('ValueError:', e)
... except ZeroDivisionError as e:
...     print('ZeroDivisionError:', e)
... else:
...     print('no error!')
... finally:
...     print('finally...')
...
try...
ValueError: invalid literal for int() with base 10: 'a'
finally...
>>> try:
...     print('try...')
...     r = 10 / int(0)
...     print('result:', r)
... except ValueError as e:
...     print('ValueError:', e)
... except ZeroDivisionError as e:
...     print('ZeroDivisionError:', e)
... else:
...     print('no error!')
... finally:
...     print('finally...')
...
try...
ZeroDivisionError: division by zero
finally...
View Code

2. raise语句

    a) 与Java的throw语句类似。

    b) 无参数raise语句:如果raise语句无任何参数,则抛出except的错误。

    c) 示例

>>> def foo(s):
...     n = int(s)
...     if n==0:
...         raise ValueError('invalid value: %s' % s)
...     return 10 / n
...
>>> def bar():
...     try:
...         foo('0')
...     except ValueError as e:
...         print('ValueError!')
...         raise
...
>>> bar()
ValueError!
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in bar
  File "<stdin>", line 4, in foo
ValueError: invalid value: 0
View Code
>>> class FooError(ValueError):
...     pass
...
>>> def foo(s):
...     n = int(s)
...     if n==0:
...         raise FooError('invalid value: %s' % s)
...     return 10 / n
...
>>> foo('0')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in foo
__main__.FooError: invalid value: 0
View Code

调试

1. 调试方法:

    a) print打印;

    b) assert断言;

    c) logging日志;

    d) pdb断点;

    e) IDE断点。

2. assert断言

    a) assert语句:表达式为False时,抛出AssertionError。

    b) 关闭assert:启动Python解释器时,可通过-O参数关闭断言,即不执行assert语句。

python -O <脚本>.py

    c) 示例

>>> def foo(s):
...     n = int(s)
...     assert n != 0, 'n is zero!'
...     return 10 / n
...
>>> foo('0')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in foo
AssertionError: n is zero!
View Code

3. logging日志

    a) logging模块:可输出日志到控制台、日志。

    b) 日志级别:可指定输出的日志级别,debug、info、warning、error。

    c) 示例

1 import logging
2 logging.basicConfig(level=logging.INFO)
3 try:
4     logging.info('try...')
5     r = 10 / int('0')
6     logging.info('result:%d' % r)
7 except ZeroDivisionError as e:
8     logging.exception(e)
View Code
INFO:root:try...
ERROR:root:division by zero
Traceback (most recent call last):
  File "d.py", line 5, in <module>
    r = 10 / int('0')
ZeroDivisionError: division by zero

单元测试

1. 测试驱动开发:TDD,Test-Driven Development。

2. 单元测试:用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。

3. 好处

    a) 确保一个程序模块的行为符合我们设计的测试用例。

    b) 如果对代码做了修改,只需要再跑一遍单元测试。如果通过,说明修改符合测试用例;如果不通过,说明修改不符合测试用例,要么修改代码,要么修改测试。

4. 单元测试编写方法

    a) 测试类须继承unittest.TestCase。

    b) 以test开头的方法是测试方法,不以test开头的方法不被认为是测试方法,测试时不会被执行。

    c) 常用断言1:self.assertEquals(x, y),期待x等于y。

    d) 常用断言2:期待抛出错误。

with self.assertRaises(<错误类型>):
    <测试的代码块>

    e) setUp()方法:在每调用一个测试方法之前分别被执行。

    f) tearDown()方法:在每调用一个测试方法之后分别被执行。

    g) 示例(mydict.py和mydict_test.py)

 1 class Dict(dict):
 2     def __init__(self, **kw):
 3         super(Dict, self).__init__(**kw)
 4     def __getattr__(self, key):
 5         try:
 6             return self[key]
 7         except KeyError:
 8             raise AttributeError(r"'Dict' object has no attribute '%s'" % key)
 9     def __setattr__(self, key, value):
10         self[key] = value
View Code
 1 import unittest
 2 from mydict import Dict
 3 class TestDict(unittest.TestCase):
 4     def test_init(self):
 5         d = Dict(a=1, b='test')
 6         self.assertEqual(d.a, 1)
 7         self.assertEqual(d.b, 'test')
 8         self.assertTrue(isinstance(d, dict))
 9     def test_key(self):
10         d = Dict()
11         d['key'] = 'value'
12         self.assertEqual(d.key, 'value')
13     def test_attr(self):
14         d = Dict()
15         d.key = 'value'
16         self.assertTrue('key' in d)
17         self.assertEqual(d['key'], 'value')
18     def test_keyerror(self):
19         d = Dict()
20         with self.assertRaises(KeyError):
21             value = d['empty']
22     def test_attrerror(self):
23         d = Dict()
24         with self.assertRaises(AttributeError):
25             value = d.empty
View Code

5. 单元测试运行方法

    a) -m unittest参数:可一次批量执行单元测试,并且有很多工具支持自动运行。

    b) 示例

python -m unittest mydict_test
.....
----------------------------------------------------------------------
Ran 5 tests in 0.001s

OK

文档测试

1. 文档测试:Python内置的doctest模块可直接提取注释中的代码并执行测试。

2. 好处:既可以用来测试,又可以直接作为示例代码。

3. 结果判断

    a) doctest严格按照Python交互式命令行的输入和输出来判断测试结果是否正确。

    b) 测试异常时,可以用...表示中间一大段烦人的输出。

4. 示例(mydict.py)

 1 class Dict(dict):
 2     '''
 3     Simple dict but also support access as x.y style.
 4 
 5     >>> d1 = Dict()
 6     >>> d1['x'] = 100
 7     >>> d1.x
 8     100
 9     >>> d1.y = 200
10     >>> d1['y']
11     200
12     >>> d2 = Dict(a=1, b=2, c='3')
13     >>> d2.c
14     '3'
15     >>> d2['empty']
16     Traceback (most recent call last):
17         ...
18     KeyError: 'empty'
19     >>> d2.empty
20     Traceback (most recent call last):
21         ...
22     AttributeError: 'Dict' object has no attribute 'empty'
23     '''
24     def __init__(self, **kw):
25         super(Dict, self).__init__(**kw)
26 
27     def __getattr__(self, key):
28         try:
29             return self[key]
30         except KeyError:
31             raise AttributeError(r"'Dict' object has no attribute '%s'" % key)
32 
33     def __setattr__(self, key, value):
34         self[key] = value
35 
36 if __name__=='__main__':
37     import doctest
38     doctest.testmod()
View Code
python mydict.py

IO编程

标准输出

1. print函数

    a) 声明

print(*objects, sep=' ', end='\n', file=sys.stdout)

    b) 官方说明:Print objects to the text stream file, separated by sep and followed by end. sep, end, file and flush, if present, must be given as keyword arguments.

2. 示例

>>> print('The quick brown fox', 'jumps over', 'the lazy dog')
The quick brown fox jumps over the lazy dog
>>> print(300)
300
>>> print(100 + 200)
300
>>> print('100 + 200 =', 100 + 200)
100 + 200 = 300
View Code

标准输入

1. input函数

    a) 声明

input([prompt])

    b) 官方说明:If the prompt argument is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that. When EOF is read, EOFError is raised.

2. 示例

>>> name = input('please enter your name: ')
please enter your name: netoxi
>>> print('hello,', name)
hello, netoxi
View Code

读文件

1. 打开文件对象:

    a) open()函数:返回file对象;如果文件不存在,则抛出IOError错误。

    b) 打开模式:r表示读文本,rb表示读二进制。

    c) codecs.open()函数:类似open()函数,但可指定字符编码,避免乱码。

2. file.read()函数:一次读取文件全部内容,返回str对象。

3. file.read(size)函数:可反复调用,每次只读取size字节的内容。

4. file.readLine()函数:可反复调用,每次只读取一行内容。

5. file.next()函数:可使用for循环file对象,每次只读取一行内容。

6. file.close()函数:关闭文件。

7. try ... finally语句:用于保证关闭文件。

8. with语句:功能同上,实现自动关闭文件,代码更简洁。

9. 示例

>>> try:
...     f = open('/home/netoxi/workspace/testpy/helloworld.py', 'r')
...     print(f.read())
... finally:
...     if f:
...         f.close()
...
#!/usr/bin/env python
print('Hello World')

>>> import codecs
>>> with codecs.open('/home/netoxi/workspace/testpy/helloworld.py', 'r', 'utf-8') as f:
...     for line in f:
...         print(line.strip())
...
#!/usr/bin/env python
print('Hello World 你好')
View Code

写文件

1. 打开文件对象:

    a) open()函数:返回file对象。

    b) 打开模式:w表示写文本(覆盖),a表示写文件(追加),wb表示写二进制(覆盖),ab表示写二进制(追加)。

    c) codecs.open()函数:类似open()函数,但可指定字符编码,避免乱码。

2. file.flush()函数:flush内部buffer。

3. file.write(str)函数:写字符串。

4. file.writelines(seq)函数:写字符串序列。

5. 示例

>>> with open('/home/netoxi/workspace/testpy/out', 'w') as f:
...     for n in range(0, 10):
...         f.write(str(n))
...     f.writelines([str(n) for n in range(0, 5)])
View Code

操作文件和目录

1. os模块:提供与操作系统相关的功能,如当前操作系统信息、当前用户信息、当前进程信息及操作、目录及文件操作等。示例:

>>> import os
>>> os.name
'posix'
>>> os.uname()
('Linux', 'netoxiubuntu', '4.4.0-92-generic', '#115-Ubuntu SMP Thu Aug 10 09:04:33 UTC 2017', 'x86_64')
>>> os.getenv('JAVA_HOME')
'/opt/installation/java/jdk1.8.0_101'
>>> os.environ
{'LC_NUMERIC': 'zh_CN.UTF-8', 'WINDOWID': '65011722', 'MANDATORY_PATH': '/usr/share/gconf/ubuntu.mandatory.path', 'XDG_GREETER_DATA_DIR': '/var/lib/lightdm-data/netoxi', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', ... }
View Code

2. os.path模块:提供路径相关操作。

    a) os.path.abspath(path)函数:返回绝对路径。

    b) os.path.exists(path)函数:判断存在。

    c) os.path.isfile(path)函数:判断普通文件。

    d) os.path.isdir(path)函数:判断目录。

    e) os.path.join(path, *paths)函数:连接路径。

    f) os.path.split(path)函数:拆分成两部分,第二部分是最后级别的目录或文件。

    g) os.path.splitext(path)函数:拆分成两部分,第二部分是扩展名。

    h) 示例

>>> os.path.abspath('.')
'/home/netoxi/workspace/testpy'
>>> os.path.exists('.')
True
>>> os.path.isfile('.')
False
>>> os.path.isdir('.')
True
>>> os.path.join('/home/netoxi/workspace', 'testpy/helloworld.py')
'/home/netoxi/workspace/testpy/helloworld.py'
>>> os.path.split('/home/netoxi/workspace/testpy/helloworld.py')
('/home/netoxi/workspace/testpy', 'helloworld.py')
>>> os.path.splitext('/home/netoxi/workspace/testpy/helloworld.py')
('/home/netoxi/workspace/testpy/helloworld', '.py')
View Code

3. 目录/文件操作

    a) os.chmod(path, mode)函数:设置权限。

    b) os.chown(path, uid, gid)函数:设置owner。

    c) os.listdir(path)函数:返回包含path下所有目录和文件名称的list。

    d) os.mkdir(path[, mode])函数:创建目录。

    e) os.remove(path)函数:删除文件;如果是目录,则抛出OSError错误。

    f) os.rename(src, dst)函数:重命名。

    g) os.rmdir(path)函数:删除目录;如果目录非空,则抛出OSError错误。

    h) 示例

>>> os.mkdir('./mydir')
>>> os.rename('./mydir', './mydir0')
>>> os.listdir('.')
['helloworld.py', 'encode.py', 'drink.jpg', 'out', 'mydir0']
>>> os.rmdir('./mydir0')
View Code

Python序列化与反序列化

1. 序列化:Python中叫pickling,把变量从内存中变成可存储或传输的过程。

2. 反序列化:Python中叫unpickling,把变量内容从序列化的对象重新读到内存。

3. cPickle和pickle模块:

    a) 相同:Python提供的两个序列化模块,功能一样

    b) 不同:前者是C语言编写、速度快,后者是Python编写、速度慢。

    c) 导入:

1 try:
2     import cPickle as pickle
3 except ImportError:
4     import pickle
View Code

4. pickle.dumps函数

    a) 声明

pickle.dumps(obj[, protocol])

    b) 官方说明:Return the pickled representation of the object as a string, instead of writing it to a file. If the protocol parameter is omitted, protocol 0 is used. If protocol is specified as a negative value or HIGHEST_PROTOCOL, the highest protocol version will be used.

5. pickle.loads函数

    a) 声明

pickle.loads(string)

    b) 官方说明:Read a pickled object hierarchy from a string. Characters in the string past the pickled object’s representation are ignored.

6. pickle.dump函数

    a) 声明

pickle.dump(obj, file[, protocol])

    b) 官方说明:Write a pickled representation of obj to the open file object file. This is equivalent to Pickler(file, protocol).dump(obj). If the protocol parameter is omitted, protocol 0 is used. If protocol is specified as a negative value or HIGHEST_PROTOCOL, the highest protocol version will be used.

7. pickle.load函数

    a) 声明

pickle.load(file)

    b) 官方说明:Read a string from the open file object file and interpret it as a pickle data stream, reconstructing and returning the original object hierarchy. This is equivalent to Unpickler(file).load().

8. 示例

>>> import cPickle as pickle
>>> d = dict(name='Bob', age=20, score=88)
>>> s = pickle.dumps(d)
>>> s
"(dp1\nS'age'\np2\nI20\nsS'score'\np3\nI88\nsS'name'\np4\nS'Bob'\np5\ns."
>>> d1 = pickle.loads(s)
>>> d1
{'age': 20, 'score': 88, 'name': 'Bob'}
View Code
>>> d = dict(name='Bob', age=20, score=88)
>>> f = open('/home/netoxi/workspace/testpy/dump.txt', 'wb')
>>> pickle.dump(d, f)
>>> f.close()
>>> f1 = open('/home/netoxi/workspace/testpy/dump.txt', 'rb')
>>> d1 = pickle.load(f1)
>>> f1.close()
>>> d1
{'age': 20, 'score': 88, 'name': 'Bob'}
View Code

JSON序列化与反序列化

1. JSON和Python数据类型对应:

JSON

Python

object

dict

array

list

string

str,unicode

number

int,long,float

true/false

True/False

null

None

2. 对象序列化与反序列化

    a) 对象序列化时,须指定default函数,将对象转为上表中的Python数据类型。

    b) 技巧:通常class实例都有__dict__属性(少数例外,如定义了__slots__的class),是存储实例变量的dict,可用于将class实例转为dict。

    c) 对象反序列化时,须指定object_hook函数,将上表中的Python数据类型转为对象。

3. json.dumps函数

    a) 声明

json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding=”utf-8”, default=None, sort_keys=False, **kw)

    b) 官方说明:Serialize obj to a JSON formatted str using this conversion table. If ensure_ascii is false, the result may contain non-ASCII characters and the return value may be a unicode instance.

4. json.loads函数

    a) 声明

json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

    b) 官方说明:Deserialize s (a str or unicode instance containing a JSON document) to a Python object using this conversion table. If s is a str instance and is encoded with an ASCII based encoding other than UTF-8 (e.g. latin-1), then an appropriate encoding name must be specified. Encodings that are not ASCII based (such as UCS-2) are not allowed and should be decoded to unicode first.

5. 示例

>>> import json
>>> d = dict(name='Bob', age=20, score=88)
>>> s = json.dumps(d)
>>> s
'{"age": 20, "score": 88, "name": "Bob"}'
>>> json.loads(s)
{u'age': 20, u'score': 88, u'name': u'Bob'}
View Code
>>> import json
>>> class Student(object):
...     def __init__(self, name, age, score):
...         self.name = name
...         self.age = age
...         self.score = score
... 
>>> s = Student('Bob', 20, 88)
>>> def student2dict(std):
...     return {
...         'name': std.name,
...         'age': std.age,
...         'score': std.score
...     }
... 
>>> json_str = json.dumps(s, default=student2dict)
>>> json_str
'{"age": 20, "score": 88, "name": "Bob"}'
>>> def dict2student(d):
...     return Student(d['name'], d['age'], d['score'])
... 
>>> json.loads(json_str, object_hook=dict2student)
<__main__.Student object at 0x7fcfa7436190>
View Code
>>> import json
>>> class Student(object):
...     def __init__(self, name, age, score):
...         self.name = name
...         self.age = age
...         self.score = score
... 
>>> s = Student('Bob', 20, 88)
>>> json.dumps(s, default=lambda obj: obj.__dict__)
'{"age": 20, "score": 88, "name": "Bob"}'
View Code

常用内建模块

collections

1. collections:Python内置集合模块,提供许多有用的集合类。

2. namedtuple函数

    a) 声明

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])

    b) 官方说明:Returns a new tuple subclass named typename. The new subclass is used to create tuple-like objects that have fields accessible by attribute lookup as well as being indexable and iterable.

    c) 说明:创建tuple子类,支持通过属性名访问(tuple仅支持通过索引访问)。

    d) 示例

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(1, 2)
>>> p.x
1
>>> p.y
2
>>> p[0]
1
>>> p[1]
2
View Code

3. deque类

    a) deque类:双向链表,插入、删除效率较高,也适合当做队列和栈。

    b) list类:线性表,插入、删除效率较低。

    c) 示例

>>> from collections import deque
>>> d = deque(['a', 'b', 'c'])
>>> d.append('x')
>>> d.appendleft('y')
>>> d
deque(['y', 'a', 'b', 'c', 'x'])
>>> d.pop()
'x'
>>> d.popleft()
'y'
View Code

4. defaultdict类

    a) defaultdict类:与dict唯一区别是,当访问的key不存在时,返回默认值。

    b) dict类:当访问的key不存在时,抛出KeyError。

    c) 示例

>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1']
'abc'
>>> dd['key2']
'N/A'
View Code

5. OrderedDict类

    a) OrderedDict类:遍历顺序为key的插入顺序。

    b) 示例

>>> from collections import OrderedDict
>>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> for x in od:
...     print(x)
... 
z
y
X
>>> od.keys()
['z', 'y', 'x']
View Code

 

作者:netoxi
出处:http://www.cnblogs.com/netoxi
本文版权归作者和博客园共有,欢迎转载,未经同意须保留此段声明,且在文章页面明显位置给出原文连接。欢迎指正与交流。

 

posted on 2017-09-18 09:09  netoxi  阅读(...)  评论(... 编辑 收藏