“Yeah It’s on. ”
- python
python
1. 语言特性:
强类型(大小写敏感)
面向对象(一切皆为对象)
2. 获取帮助
help(<object>)
dir()显示该对象的所有方法
<object>._d显示其文档
3. 语法
- (#)井号表示之后为字符为python的注释
- (“”” a = 1 “””) 多行注释
- (\n)换行是标准的行分隔符
- (\)反斜线表示继续上一行
- (;)分隔同一行多个语句
- (:)冒号表示将代码块的头和体分开
- 语句(代码块)用于缩进的方式体现
- 不同的缩进深度分隔不同的代码块
- python文件以模块的形式组织
- 赋值
# python 中对象通过引用传递 x = x+1 # 增量赋值 x += 1 # 多重赋值 x = y = z = 1 # 将同一个引用赋值给x,y,z # 多元赋值 (x,y,z)=(1,2,'a string')
- 标识符
- 第一个字符必须是字母或者下划线(_)
- 剩下的字符可以是字符和数字或下划线。
- 大小写敏感
- 变量(避免下划线开头,无需声明)
- xxx 系统定义名字
- _xxx 类中的私有变量名
- 内存管理
- 变量无须事先声明
- 变量无须指定类型
- 程序员不用关心内存管理
- 变量名会被“回收”
- del语句能够直接释放资源
4. 数据类型
列表(list)、元组(tuple)、字典(dictionaries)三种基本数据结构
常量:大写
- List: 内置数据类型,有序集合,元素类型可不同,可随时添加和删除元素:.insert(i) .pop(i)
- Tuple: 初始化后不能修改
5. dict 和 set
- dict的key必须是不可变对象
- set和dict类似,也是一组key的集合,但不存储value,无重复元素(两个set可以做数学意义上的交集、并集等操作)
和list比较,dict有以下几个特点:
- 查找和插入的速度极快,不会随着key*的增加而增加;
- 需要占用大量的内存,内存浪费多。 而list相反:
- 查找和插入的时间随着元素的增加而增加;
- 占用空间小,浪费内存很少。 所以,dict是用空间来换取时间的一种方法。
6. 流程控制
if for while range(
7. 函数
def声明 参数通过引用传递,但对于不可变类型(元组、整数、字符串)不改变
7.1. 默认参数
指向不变对象(str,None)
7.2. 可变参数
def calc(*num)
7.3. 关键字参数
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
def person(name, age, **kw):
print 'name:', name, 'age:', age, 'other:', kw
>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
# 用 in 和 not in 来检查某个键是否在字典中
7.4. 参数组合
参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。
def func(a, b, c=0, *args, **kw):
print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw
# *args是可变参数,args接收的是一个tuple;
# **kw是关键字参数,kw接收的是一个dict。
7.5. 递归函数
尾递归优化
def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num - 1, num * product)
7.6. 切片
L[0:3](表示从索引0开始到索引3为止,0,1,2)
L = range(100)
L[:10] # 前10个数
L[-10:] # 后10个数
L[:10:2] #前10个数,每两个取一个
L[::5] #所有数,每5个取一个
L[:] #复制一个list
7.7. 迭代 for … in
d = {'a': 1, 'b': 2, 'c': 3}
for key in d # 迭代key
for value in d.itervalues() # 迭代value
for k, v in d.iteritems() # 迭代key,value
# 判断是否为可迭代对象-通过collections模块的iterable类型判断
from collections import Iterable
isinstance('abc', Iterable) # str是否可迭代 true
7.8. 列表生成式
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 还可以加上if判断
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
7.9. 生成器
列表元素可以按照某种算法推算出来,节省空间
# 将[]直接换成()
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x104feab40>
# 可用next()或for循环
>>> g.next()
0
>>> g.next()
1
8. 函数式编程
8.1. 高阶函数
-
map 接受两个参数(函数,序列) 将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。
>>> def f(x): ... return x * x ... >>> map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) [1, 4, 9, 16, 25, 36, 49, 64, 81]
-
reduce reduce把一个函数作用在一个序列[x1, x2, x3…]上 必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4) # 比方说对一个序列求和,就可以用reduce实现: >>> def add(x, y): ... return x + y ... >>> reduce(add, [1, 3, 5, 7, 9]) 25
-
filter 与map 类似:接收参数:一个函数、一个序列 不同:依次作用于每个元素,根据返回值true/false决定是否保留
def not_empty(s): return s and s.strip() filter(not_empty, ['A', '', 'B', None, 'C', ' ']) # 结果: ['A', 'B', 'C']
- sorted
-
lambda 限制:只能有一个表达式,不用写return,返回值就是该表达式的结果
lambda x: x * x # 相当于 def f(x): return x * x
9. 模块
9.1. 模块格式
#!/usr/bin/env python ——标准注释:该注释可以让此文件直接在Unix/Linux/Mac上运行
# -*- coding: utf-8 -*- ——标准注释:表示此文件本身使用标准UTF-8编码
' a test module ' # 模块的文档注释——任何模块代码的第一个字符串都被视为模块的文档注释
__author__ = 'Michael Liao' # 作者名字
import sys # 导入模块,模块argv变量用list存储了命令行所有参数
# 运行python hello.py获得的sys.argv就是['hello.py'];
# 运行python hello.py Michael获得的sys.argv就是['hello.py', 'Michael]。
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()
9.2 作用域
- public: abc,x123
- 特殊变量: xxx 可被直接引用(特殊用途如:author,name)
- __name__指示模块应如何被加载
- 如果模块是被导入,__name__的值为模块名字
- 如果模块是被直接执行,name__的值为‘ __main ’
- private: _xxx/__xxx,不应该直接引用
def _private_1(name):
return 'Hello, %s' % name
def _private_2(name):
return 'Hi, %s' % name
def greeting(name):
if len(name) > 3:
return _private_1(name)
else:
return _private_2(name)
# 模块公开greeting函数,内部逻辑用private隐藏
# 外部不需要引用的函数全部定义成private,只有需要引用的函数public
10. 面向对象编程
数据封装、继承和多态只是面向对象程序设计中最基础的3个概念 私有变量/方法(惯例):至少两个前导下划线&至多尾随一个下划线(__spam)
- python 中任何类型的值都是一个对象
- None——Python的Null对象
10.1 与面向过程
# 面向过程
# 成绩表示
std1 = { 'name': 'Michael', 'score': 98 }
std2 = { 'name': 'Bob', 'score': 81 }
# 成绩处理
def print_score(std):
print '%s: %s' % (std['name'], std['score'])
# 面向对象
class Student(object): # class 类名(-大写开头) (object-继承哪个类)
def __init__(self, name, score): # 创建实例时绑定必要属性
self.name = name # self:创建的实例本身
self.score = score
def print_score(self):
print '%s: %s' % (self.name, self.score)
# 对象操作
bart = Student('Bart Simpson', 59) # 类名+() 创建实例
lisa = Student('Lisa Simpson', 87)
lisa.school = 'huagong' # 可自由绑定属性
bart.print_score()
lisa.print_score()
# 访问限制
# 之前还能访问name,score属性,若限制保护内部变量
self.__name = name
self.__score = score
# 原因:Python解释器对外把__name变量改成了_Student__name
>>> bart._Student__name
'Bart Simpson'
# 获取方法
# 给Student类增加get_name和get_score
class Student(object):
...
def get_name(self):
return self.__name
def set_score(self, score): # 修改
self.__score = score
10.2. 与普通函数
第一个参数永远是实例变量self,调用时不用传递该参数 特点
- 类是创建实例的模板,而实例则是一个个具体对象,各个实例拥有的数据都互相独立
- 方法就是与实例绑定的函数,可以直接访问实例的数据
- 允许对实例变量绑定任何数据,不同实例变量可能不同
10.3. 多态
class Animal(object):
def run(self):
print 'Animal is running...'
class Dog(Animal):
def run(self):
print 'Dog is running...'
dog = Dog()
>>> dog.run()
>>> Dog is running...
10.4. 判断变量类型
# 判断一个变量是否是某个类型可以用isinstance()判断:
a = list() # a是list类型
b = Animal() # b是Animal类型
>>> isinstance(a, list)
True
>>> isinstance(b, Animal)
True
11. 获取对象信息
11.1. type()
判断基本类型
>>> type(123)
<type 'int'>
>>> type('str')
<type 'str'>
>>> type(None)
<type 'NoneType'>
# 函数或类
>>> type(abs)
<type 'builtin_function_or_method'>
>>> type(a)
<class '__main__.Animal'>
# types模块
>>> import types
>>> type('abc')==types.StringType
True
>>> type([])==types.ListType
True
>>> type(str)==types.TypeType # 所有类型本身的类型就是TypeType
True
11.2. isinstance()
判断class类型
h = Husky()
>>> isinstance(h, Husky) # 父类也可以
True
# 基本类型也可以
>>> isinstance('a', str)
True
# 判断是否属于一种
>>> isinstance('a', (str, unicode))
True
11.3. dir()
获取对象的所有属性和方法
dir('abc')
配合getattr()、setattr()以及hasattr(),可以直接操作一个对象的状态:
>>> class MyObject(object):
def __init__(self):
self.x = 9
def power(self):
return self.x * self.x
>>> obj = MyObject()
紧接着,可以测试该对象的属性:
>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19
# 若不存在,返回默认值
>>> getattr(obj, 'z', 404)
404
11. 面向对象高级编程
11.1. slots
限制class属性,仅对当前类起作用,对继承的子类不起作用
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
s = Student() # 创建新的实例
s.score = 99 # 绑定属性'score'
# 由于'score'没有被放到__slots__中,所以不能绑定score属性,试图绑定score将得到AttributeError的错误。
11.2. @property
用在类定义中,将方法转化为属性,代码简短,调用简单
class Student(object):
def get_score(self):
return self._score
def set_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
>>> s = Student()
>>> s.set_score(60) # ok!
>>> s.get_score()
60
# 转化为可直接调用的属性
class Student(object):
@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
>>> s = Student()
>>> s.score = 60 # OK,实际转化为s.set_score(60)
>>> s.score # OK,实际转化为s.get_score()
60
11.3. 多重继承
子类同时获得多个父类的所有功能
class Dog(Mammal, Runnable):
pass
# mixin
# python自带功能库
12. 异常
try-except[exceptionname]
try:
print 'try...'
r = 10 / 0
print 'result:', r
except ZeroDivisionError, e:
print 'except:', e
else:
print 'no error!'
finally:
print 'finally...'
print 'END'
# 结果
try...
except: integer division or modulo by zero
finally...
END
13. 调试
- assert
# err.py
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n
def main():
foo('0')
# 若断言失败
$ python err.py
Traceback (most recent call last):
...
AssertionError: n is zero!
# 关闭断言
$ python -O err.py
- logging
14. IO
14.1. 文件读写
- 读文件
# open()函数,传入文件名和标示符
f = open('/Users/michael/test.txt', 'r')
# read()方法一次读取文件的全部内容,把内容读到内存,用一个str对象表示
f.read() # 'Hello, world!'
# close()方法关闭文件(以防占用操作系统的资源)
f.close()
# IOError,一旦出错,后面的f.close()不会调用
# 为了保证无论是否出错都能正确地关闭文件,使用try ... finally
try:
f = open('/path/to/file', 'r')
print f.read()
finally:
if f:
f.close()
# with语句: 自动调用close
with open('/path/to/file', 'r') as f:
print f.read()
其他读取方式
read() # 一次性读取文件的全部内容
readline() # 每次读取一行内容
readlines() # 一次读取所有内容并按行返回list
其他文件
# file-like object
# 像open()函数返回的这种有个read()方法的对象,在Python中统称为file-like Object
# 二进制文件(图片、视频等等)
f = open('/Users/michael/test.jpg', 'rb')
f.read()
- 写文件
区别:调用open()函数时,传入标识符’w’或者’wb’表示写文本文件或写二进制文件
f = open('/Users/michael/test.txt', 'w')
f.write('Hello, world!')
f.close()
# 写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘
# with 保险方法
with open('/Users/michael/test.txt', 'w') as f:
f.write('Hello, world!')