1、概述
Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言。
Python为咱们提供了很是完善的基础代码库,覆盖了网络、文件、GUI、数据库、文本等大量内容,被形象地称做“内置电池(batteries included)”。用Python开发,许多功能没必要从零编写,直接使用现成的便可。
龟叔给Python的定位是“优雅”、“明确”、“简单”,因此Python程序看上去老是简单易懂,初学者学Python,不但入门容易,并且未来深刻下去,能够编写那些很是很是复杂的程序。html
那Python适合开发哪些类型的应用呢?
首选是网络应用,包括网站、后台服务等等; - PythonWeb
其次是许多平常须要的小工具,包括系统管理员须要的脚本任务等等; - Python
另外就是把其余语言开发的程序再包装起来,方便使用。 - 胶水语言
在 爬虫 科学计算 等领域有独特优点
AIjava
Python的优势
简单易学
完善的语言特性python
自然开源shell
丰富的社区支持数据库
Python的缺点。
第一个缺点就是运行速度慢,和C程序相比很是慢,由于Python是解释型语言,你的代码在执行时会一行一行地翻译成CPU能理解的机器码,这个翻译过程很是耗时,因此很慢。而C程序是运行前直接编译成CPU能执行的机器码,因此很是快。
可是大量的应用程序不须要这么快的运行速度,由于用户根本感受不出来。例如开发一个下载MP3的网络应用程序,C程序的运行时间须要0.001秒,而Python程序的运行时间须要0.1秒,慢了100倍,但因为网络更慢,须要等待1秒,你想,用户能感受到1.001秒和1.1秒的区别吗?这就比如F1赛车和普通的出租车在北京三环路上行驶的道理同样,虽然F1赛车理论时速高达400千米,但因为三环路堵车的时速只有20千米,所以,做为乘客,你感受的时速永远是20千米。
第二个缺点就是代码不能加密。若是要发布你的Python程序,实际上就是发布源代码,这一点跟C语言不一样,C语言不用发布源代码,只须要把编译后的机器码(也就是你在Windows上常见的xxx.exe文件)发布出去。要从机器码反推出C代码是不可能的,因此,凡是编译型的语言,都没有这个问题,而解释型的语言,则必须把源码发布出去。express
2、安装配置
安装包下载地址:
http://www.python.org/download/编程
Python目前分为两大版本,互不兼容:
2.x.x
3.x.x
下载的时候要注意区分 根据须要的版本进行下载 目前二者都有所使用
双击安装json
设置环境变量:
将python安装位置配置到PATH环境变量下。windows
3、运行方式
shell方式:
在cmd窗口中输入python进入命令行模式 在其中以交互式方式执行数组
shell方式调用py文件:
在文件中编写Python脚本 文件后缀为.py
进入该文件所在目录 直接执行./xxx.py
IDE模式:
pycharm
pyDev for Eclipse
**Python编码
Python默认读取py文件时采用的编码格式是 ASCII 格式,若是文件不是该格式极可能出现乱码问题形成异常。
解决方法为只要在文件开头加入 # -*- coding: UTF-8 -*- 或者 #coding=utf-8 来通知Python解释器在读取文件时采用的编码集
4、标识符
在 Python 中,全部标识符能够包括英文、数字以及下划线(_),但不能以数字开头。
Python 中的标识符是区分大小写的。
如下划线开头的标识符是有特殊意义的。
以单下划线开头 _foo 的表明不能直接访问的类属性,需经过类提供的接口进行访问,不能用 from xxx import * 而导入;
以双下划线开头的 __foo 表明类的私有成员;以双下划线开头和结尾的 __foo__ 表明 Python 里特殊方法专用的标识,如 __init__() 表明类的构造函数。
5、语言细节
1.语句
Python一般一行为一条语句 不须要分号标识
Python 能够同一行显示多条语句,方法是用分号 ;
案例:
print 'hello';print 'runoob';
也可使用反斜杠将一行语句分为多行解释:
案例:
total = item_one + \
item_two + \
item_three
可是语句中[] {} () 中的内容不须要使用多行链接符。
一个标识符也不能用多行链接符隔开
2.缩进
Python 中不使用{}来标识做用范围,而是用缩进来标识,因此Python中缩进式要严格遵循结构。
3.注释
使用#做为单行注释
使用三个单引号或三个双引号做为多行注释
6、变量/常量类型
Python中的变量/常量不须要声明符 直接写便可
Python中的变量/常量不区分类型
同一个变量能够被屡次赋值为不一样类型的值
x="abc"
x=123
x = y = z = 999
x,y,z=1,2,"abc"
Python中的变量一般用小写表示
Python中的常量一般用大写表示
Python中的常量并不会受到保护 若是真的改是不会报错的 因此能够认为Python中并不真正存在语言意义上的常量 而是约定经过大写的变量标明它是一个常量 后续不要修改。
7、数据类型
虽然引用没有数据类型 可是Python是有数据类型的概念的
参看文档
1.字符串
字符串直接量
能够用单引号 双引号 三引号引发来做为字符串直接量
'abc'
"abc"
'''abc'''
"""abc"""
在声明字符串直接量时单引号和双引号没什么区别
而三引号声明的字符串中能够包含任意字符 这些字符会被直接看成字符串的内容
Python中并不存在相似java中char的字符类型 想要表示一个字符 写成一个长度为1的字符串便可
字符串操做符
+ 字符串链接
>>>a + b
'HelloPython'
* 重复输出字符串
>>>a * 2
'HelloHello'
[] 经过索引获取字符串中字符
>>>a[1]
'e'
[ : ] 截取字符串中的一部分
>>>a[1:4]
'ell'
in 成员运算符 - 若是字符串中包含给定的字符返回 True
>>>"H" in a
True
not in 成员运算符 - 若是字符串中不包含给定的字符返回 True
>>>"M" not in a
True
r/R 原始字符串 - 原始字符串:全部的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母"r"(能够大小写)之外,与普通字符串有着几乎彻底相同的语法。
>>>print r'\n'
\n
>>> print R'\n'
\n
% 格式字符串
格式化字符串
%c 格式化字符及其ASCII码
%s 格式化字符串
%d 格式化整数
%u 格式化无符号整型
%o 格式化无符号八进制数
%x 格式化无符号十六进制数
%X 格式化无符号十六进制数(大写)
%f 格式化浮点数字,可指定小数点后的精度
%e 用科学计数法格式化浮点数
%E 做用同%e,用科学计数法格式化浮点数
%g %f和%e的简写
%G %f 和 %E 的简写
%p 用十六进制数格式化变量的地址
案例:
print "My name is %s and weight is %d kg!" % ('Zara', 21)
2.布尔类型
直接量只有两个 True False
布尔类型的与或非 and or not
3.数值类型:
整型(Int) - 一般被称为是整型或整数,是正或负整数,不带小数点。
长整型(long integers) - 无限大小的整数,整数最后是一个大写或小写的L。
浮点型(floating point real values) - 浮点型由整数部分与小数部分组成,浮点型也可使用科学计数法表示(2.5e2 = 2.5 x 102 = 250)
复数(complex numbers) - 复数由实数部分和虚数部分构成,能够用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型。
类型转换:
!!int(x [,base ]) 将x转换为一个整数
!!long(x [,base ]) 将x转换为一个长整数
!!float(x ) 将x转换到一个浮点数
complex(real [,imag ]) 建立一个复数
!!str(x ) 将对象 x 转换为字符串
repr(x ) 将对象 x 转换为表达式字符串
!!eval(str ) 用来计算在字符串中的有效Python表达式,并返回一个对象
tuple(s ) 将序列 s 转换为一个元组
list(s ) 将序列 s 转换为一个列表
chr(x ) 将一个整数转换为一个字符
unichr(x ) 将一个整数转换为Unicode字符
ord(x ) 将一个字符转换为它的整数值
hex(x ) 将一个整数转换为一个十六进制字符串
oct(x ) 将一个整数转换为一个八进制字符串
数学函数:
abs(x) 返回数字的绝对值,如abs(-10) 返回 10
ceil(x) 返回数字的上入整数,如math.ceil(4.1) 返回 5
cmp(x, y) 若是 x < y 返回 -1, 若是 x == y 返回 0, 若是 x > y 返回 1
exp(x) 返回e的x次幂(ex),如math.exp(1) 返回2.718281828459045
fabs(x) 返回数字的绝对值,如math.fabs(-10) 返回10.0
floor(x) 返回数字的下舍整数,如math.floor(4.9)返回 4
log(x) 如math.log(math.e)返回1.0,math.log(100,10)返回2.0
log10(x) 返回以10为基数的x的对数,如math.log10(100)返回 2.0
max(x1, x2,...) 返回给定参数的最大值,参数能够为序列。
min(x1, x2,...) 返回给定参数的最小值,参数能够为序列。
modf(x) 返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。
pow(x, y) x**y 运算后的值。
round(x [,n]) 返回浮点数x的四舍五入值,如给出n值,则表明舍入到小数点后的位数。
sqrt(x) 返回数字x的平方根,数字能够为负数,返回类型为实数,如math.sqrt(4)返回 2+0j
随机数函数
choice(seq) 从序列的元素中随机挑选一个元素,好比random.choice(range(10)),从0到9中随机挑选一个整数。
randrange ([start,] stop [,step]) 从指定范围内,按指定基数递增的集合中获取一个随机数,基数缺省值为1
random() 随机生成下一个实数,它在[0,1)范围内。
seed([x]) 改变随机数生成器的种子seed。若是你不了解其原理,你没必要特别去设定seed,Python会帮你选择seed。
shuffle(lst) 将序列的全部元素随机排序
uniform(x, y) 随机生成下一个实数,它在[x,y]范围内。
数学常量
pi 数学常量 pi(圆周率,通常以π来表示)
e 数学常量 e,e即天然常数(天然常数)
4.空值
None
8、运算符
算术运算符
+ 加 - 两个对象相加 a + b 输出结果 30
- 减 - 获得负数或是一个数减去另外一个数 a - b 输出结果 -10
* 乘 - 两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200
/ 除 - x除以y b / a 输出结果 2
% 取模 - 返回除法的余数 b % a 输出结果 0
** 幂 - 返回x的y次幂 a**b 为10的20次方, 输出结果 100000000000000000000
// 取整除 - 返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0
比较(关系)运算符
== 等于 - 比较对象是否相等 (a == b) 返回 False。
!= 不等于 - 比较两个对象是否不相等 (a != b) 返回 true.
<> 不等于 - 比较两个对象是否不相等 (a <> b) 返回 true。这个运算符相似 != 。
> 大于 - 返回x是否大于y (a > b) 返回 False。
< 小于 - 返回x是否小于y。全部比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。注意,这些变量名的大写。 (a < b) 返回 true。
>= 大于等于 - 返回x是否大于等于y。 (a >= b) 返回 False。
<= 小于等于 - 返回x是否小于等于y。 (a <= b) 返回 true。
赋值运算符
= 简单的赋值运算符 c = a + b 将 a + b 的运算结果赋值为 c
+= 加法赋值运算符 c += a 等效于 c = c + a
-= 减法赋值运算符 c -= a 等效于 c = c - a
*= 乘法赋值运算符 c *= a 等效于 c = c * a
/= 除法赋值运算符 c /= a 等效于 c = c / a
%= 取模赋值运算符 c %= a 等效于 c = c % a
**= 幂赋值运算符 c **= a 等效于 c = c ** a
//= 取整除赋值运算符 c //= a 等效于 c = c // a
位运算符
& 按位与运算符:参与运算的两个值,若是两个相应位都为1,则该位的结果为1,不然为0 (a & b) 输出结果 12 ,二进制解释: 0000 1100
| 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 (a | b) 输出结果 61 ,二进制解释: 0011 1101
~ 按位取反运算符:对数据的每一个二进制位取反,即把1变为0,把0变为1 (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。
^ 按位异或运算符:当两对应的二进位相异时,结果为1 (a ^ b) 输出结果 49 ,二进制解释: 0011 0001
<< 左移动运算符:运算数的各二进位所有左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 a << 2 输出结果 240 ,二进制解释: 1111 0000
>> 右移动运算符:把">>"左边的运算数的各二进位所有右移若干位,">>"右边的数指定移动的位数 a >> 2 输出结果 15 ,二进制解释: 0000 1111
逻辑运算符
and x and y 布尔"与" - 若是 x 为 False,x and y 返回 False,不然它返回 y 的计算值。 (a and b) 返回 20。
or x or y 布尔"或" - 若是 x 是非 0,它返回 x 的值,不然它返回 y 的计算值。 (a or b) 返回 10。
not not x 布尔"非" - 若是 x 为 True,返回 False 。若是 x 为 False,它返回 True。 not(a and b) 返回 False
成员运算符
in 若是在指定的序列中找到值返回 True,不然返回 False。 x 在 y 序列中 , 若是 x 在 y 序列中返回 True。
not in 若是在指定的序列中没有找到值返回 True,不然返回 False。 x 不在 y 序列中 , 若是 x 不在 y 序列中返回 True。
身份运算符
is is是判断两个标识符是否是引用自一个对象 x is y, 若是 id(x) 等于 id(y) , is 返回结果 1
is not is not是判断两个标识符是否是引用自不一样对象 x is not y, 若是 id(x) 不等于 id(y). is not 返回结果 1
**运算符优先级
** 指数 (最高优先级)
~ + - 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@)
* / % // 乘,除,取模和取整除
+ - 加法减法
>> << 右移,左移运算符
& 位 'AND'
^ | 位运算符
<= < > >= 比较运算符
<> == != 等于运算符
= %= /= //= -= += *= **= 赋值运算符
is is not 身份运算符
in not in 成员运算符
not or and 逻辑运算符
9、条件语句
if 判断条件:
执行语句……
else:
执行语句……
if 判断条件1:
执行语句1……
elif 判断条件2:
执行语句2……
elif 判断条件3:
执行语句3……
else:
执行语句4……
10、循环语句
1.while
while 判断条件:
执行语句……
while 判断条件:
执行语句……
else:
循环条件为false时执行else语句块
**支持continue、break、pass
2.for
for iterating_var in sequence:
执行语句……
for index in range:
执行语句……
for.... else... #循环条件为false时执行else语句块
**range()函数能够生成一个整数序列包含指定范围内的数据 再经过list()函数能够转换为一个List
List(range(5))
sum = 0
for x in range(101):
sum = sum + x
print(sum)
3.列表生成式
生成[1x1, 2x2, 3x3, ..., 10x10]:
[x * x for x in range(1, 11)]
for循环后面还能够加上if判断:
[x * x for x in range(1, 11) if x % 2 == 0]
还可使用两层循环
[m + n for m in 'ABC' for n in 'XYZ']
for循环其实能够同时使用两个甚至多个变量
d = {'x': 'A', 'y': 'B', 'z': 'C' }
[k + '=' + v for k, v in d.iteritems()]
生成['y=B', 'x=A', 'z=C']
11、集合
1.列表 - List
内容可变 长度可变 类型能够不一样 有序
定义列表:
list1 = ['physics', 'chemistry', 1997, 2000];
list2 = [1, 2, 3, 4, 5 ];
list3 = ["a", "b", "c", "d"];
获取列表数据:
list1[1]
list2[1:5]
更新列表:
list[2] = 2001;
删除元素:
del list1[2];
列表函数:
len([1, 2, 3]) 3 长度
[1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] 组合
['Hi!'] * 4 ['Hi!', 'Hi!', 'Hi!', 'Hi!'] 重复
3 in [1, 2, 3] True 元素是否存在于列表中
for x in [1, 2, 3]: print x, 1 2 3 迭代
列表截取:
L[2] 'SPAM!' 读取列表中第三个元素
L[-2] 'Spam' 读取列表中倒数第二个元素
L[1:] ['Spam', 'SPAM!'] 从第二个元素开始截取列表
其余方法:
cmp(list1, list2)
比较两个列表的元素
len(list)
列表元素个数
max(list)
返回列表元素最大值
min(list)
返回列表元素最小值
list(seq)
将元组转换为列表
list.append(obj)
在列表末尾添加新的对象
list.count(obj)
统计某个元素在列表中出现的次数
list.extend(seq)
在列表末尾一次性追加另外一个序列中的多个值(用新列表扩展原来的列表)
list.index(obj)
从列表中找出某个值第一个匹配项的索引位置
list.insert(index, obj)
将对象插入列表
list.pop(obj=list[-1])
移除列表中的一个元素(默认最后一个元素),而且返回该元素的值
list.remove(obj)
移除列表中某个值的第一个匹配项
list.reverse()
反向列表中元素
list.sort([func])
对原列表进行排序
2.元组
不能修改的列表
定义元组:
tup1 = ('physics', 'chemistry', 1997, 2000);
tup2 = (1, 2, 3, 4, 5 );
tup3 = "a", "b", "c", "d";
tup1 = ();
tup1 = (50,);#元组中只包含一个元素时,须要在元素后面添加逗号
访问元组:
tup1[0]
tup2[1:5]
修改元组:
元组是不容许修改的 可是能够进行链接组合
tup1 = (12, 34.56);
tup2 = ('abc', 'xyz');
tup3 = tup1 + tup2;
print tup3;
删除元组:
元组中的元素值是不容许删除的,但咱们可使用del语句来删除整个元组
tup = ('physics', 'chemistry', 1997, 2000);
del tup;
其余运算:
len((1, 2, 3)) 3 计算元素个数
(1, 2, 3) + (4, 5, 6) (1, 2, 3, 4, 5, 6) 链接
('Hi!',) * 4 ('Hi!', 'Hi!', 'Hi!', 'Hi!') 复制
3 in (1, 2, 3) True 元素是否存在
for x in (1, 2, 3): print x, 1 2 3 迭代
L[2] 'SPAM!' 读取第三个元素
L[-2] 'Spam' 反向读取;读取倒数第二个元素
L[1:] ('Spam', 'SPAM!') 截取元素
cmp(tuple1, tuple2)
比较两个元组元素。
len(tuple)
计算元组元素个数。
max(tuple)
返回元组中元素最大值。
min(tuple)
返回元组中元素最小值。
tuple(seq)
将列表转换为元组。
3.字典 - 至关于java中的map
建立字典:
d = {key1 : value1, key2 : value2,... }
键必须是惟一的,但值则没必要。
值能够取任何数据类型,但键必须是不可变的,如字符串,数字或元组。
字典中的内容无序
访问字典:
dict['Name']
修改字典:
dict['Age'] = 8; # update existing entry
dict['School'] = "DPS School"; # Add new entry
删除字典:
del dict['Name']; # 删除键是'Name'的条目
dict.clear(); # 清空词典全部条目
del dict ; # 删除词典
其余方法:
cmp(dict1, dict2)
比较两个字典元素。
len(dict)
计算字典元素个数,即键的总数。
str(dict)
输出字典可打印的字符串表示。
type(variable)
返回输入的变量类型,若是变量是字典就返回字典类型。
dict.clear()
删除字典内全部元素
dict.copy()
返回一个字典的浅复制
dict.fromkeys(seq[, val]))
建立一个新字典,以序列 seq 中元素作字典的键,val 为字典全部键对应的初始值
dict.get(key, default=None)
返回指定键的值,若是值不在字典中返回default值
dict.has_key(key)
若是键在字典dict里返回true,不然返回false
dict.items()
以列表返回可遍历的(键, 值) 元组数组
dict.keys()
以列表返回一个字典全部的键
dict.setdefault(key, default=None)
和get()相似, 但若是键不存在于字典中,将会添加键并将值设为default
dict.update(dict2)
把字典dict2的键/值对更新到dict里
dict.values()
以列表返回字典中的全部值
4.set
set和dict相似,也是一组key的集合,但不存储value。因为key不能重复,因此,在set中,没有重复的key。
要建立一个set,须要提供一个list做为输入集合:
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}
12、日期和时间
1.time 时间戳
ticks = time.time()
localtime = time.localtime(time.time())
0 tm_year 2008
1 tm_mon 1 到 12
2 tm_mday 1 到 31
3 tm_hour 0 到 23
4 tm_min 0 到 59
5 tm_sec 0 到 61 (60或61 是闰秒)
6 tm_wday 0到6 (0是周一)
7 tm_yday 1 到 366(儒略历)
8 tm_isdst -1, 0, 1, -1是决定是否为夏令时的旗帜
格式化时间:
localtime = time.asctime( time.localtime(time.time()) )
time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
其余方法:
1 time.altzone
返回格林威治西部的夏令时地区的偏移秒数。若是该地区在格林威治东部会返回负值(如西欧,包括英国)。对夏令时启用地区才能使用。
2 time.asctime([tupletime])
接受时间元组并返回一个可读的形式为"Tue Dec 11 18:07:14 2008"(2008年12月11日 周二18时07分14秒)的24个字符的字符串。
3 time.clock( )
用以浮点数计算的秒数返回当前的CPU时间。用来衡量不一样程序的耗时,比time.time()更有用。
4 time.ctime([secs])
做用至关于asctime(localtime(secs)),未给参数至关于asctime()
5 time.gmtime([secs])
接收时间辍(1970纪元后通过的浮点秒数)并返回格林威治天文时间下的时间元组t。注:t.tm_isdst始终为0
6 time.localtime([secs])
接收时间辍(1970纪元后通过的浮点秒数)并返回当地时间下的时间元组t(t.tm_isdst可取0或1,取决于当地当时是否是夏令时)。
7 time.mktime(tupletime)
接受时间元组并返回时间辍(1970纪元后通过的浮点秒数)。
8 time.sleep(secs)
推迟调用线程的运行,secs指秒数。
9 time.strftime(fmt[,tupletime])
接收以时间元组,并返回以可读字符串表示的当地时间,格式由fmt决定。
10 time.strptime(str,fmt='%a %b %d %H:%M:%S %Y')
根据fmt的格式把一个时间字符串解析为时间元组。
11 time.time( )
返回当前时间的时间戳(1970纪元后通过的浮点秒数)。
12 time.tzset()
根据环境变量TZ从新初始化时间相关设置。
2.calendar 日历
cal = calendar.month(2016, 1)
1 calendar.calendar(year,w=2,l=1,c=6)
返回一个多行字符串格式的year年年历,3个月一行,间隔距离为c。 每日宽度间隔为w字符。每行长度为21* W+18+2* C。l是每星期行数。
2 calendar.firstweekday( )
返回当前每周起始日期的设置。默认状况下,首次载入caendar模块时返回0,即星期一。
3 calendar.isleap(year)
是闰年返回True,不然为false。
4 calendar.leapdays(y1,y2)
返回在Y1,Y2两年之间的闰年总数。
5 calendar.month(year,month,w=2,l=1)
返回一个多行字符串格式的year年month月日历,两行标题,一周一行。每日宽度间隔为w字符。每行的长度为7* w+6。l是每星期的行数。
6 calendar.monthcalendar(year,month)
返回一个整数的单层嵌套列表。每一个子列表装载表明一个星期的整数。Year年month月外的日期都设为0;范围内的日子都由该月第几日表示,从1开始。
7 calendar.monthrange(year,month)
返回两个整数。第一个是该月的星期几的日期码,第二个是该月的日期码。日从0(星期一)到6(星期日);月从1到12。
8 calendar.prcal(year,w=2,l=1,c=6)
至关于 print calendar.calendar(year,w,l,c).
9 calendar.prmonth(year,month,w=2,l=1)
至关于 print calendar.calendar(year,w,l,c)。
10 calendar.setfirstweekday(weekday)
设置每周的起始日期码。0(星期一)到6(星期日)。
11 calendar.timegm(tupletime)
和time.gmtime相反:接受一个时间元组形式,返回该时刻的时间辍(1970纪元后通过的浮点秒数)。
12 calendar.weekday(year,month,day)
返回给定日期的日期码。0(星期一)到6(星期日)。月份为 1(一月) 到 12(12月)。
十3、函数
函数定义:
普通函数定义:
函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()和冒号。
任何传入参数和自变量必须放在圆括号中间。圆括号之间能够用于定义参数。
函数的第一行语句能够选择性地使用文档字符串—用于存放函数说明。
函数内容须要缩进。
return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return至关于返回 None。
def functionname( parameters ):
"函数_文档字符串"
function_suite
return [expression]
匿名函数定义 - lambda表达式 - 函数直接量:
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2;
# 调用sum函数
print "相加后的值为 : ", sum( 10, 20 )
print "相加后的值为 : ", sum( 20, 20 )
函数调用:
定义一个函数只给了函数一个名称,指定了函数里包含的参数,和代码块结构。
def printme( str ):
"打印任何传入的字符串"
print str;
return;
printme("My string");
printme(str = "My string");
缺省参数:
def printinfo( name, age = 35 ):
"打印任何传入的字符串"
print "Name: ", name;
print "Age ", age;
return;
printinfo( age=50, name="miki" );
printinfo( name="miki" );
不定长参数 - 可变参数:
def functionname([formal_args,] *var_args_tuple ):
"函数_文档字符串"
function_suite
return [expression]
空函数
若是想定义一个什么事也不作的空函数,能够用pass语句:
def nop():
pass
pass语句什么都不作,那有什么用?实际上pass能够用来做为占位符,好比如今还没想好怎么写函数的代码,就能够先放一个pass,让代码能运行起来。
pass还能够用在其余语句里,好比:
if age >= 18:
pass
缺乏了pass,代码运行就会有语法错误。
函数是一等公民
能够做为类的成员使用
能够做为局部成员定义在另外一个函数的内部
能够被赋值给常量变量
能够做为另外一个函数的参数被传递 被看成另外一个函数的返回值被返回
闭包问题
十4、模块
Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
模块让你可以有逻辑地组织你的 Python 代码段。
把相关的代码分配到一个模块里能让你的代码更好用,更易懂。
模块能定义函数,类和变量,模块里也能包含可执行的代码。
引入模块
import module1[, module2[,... moduleN]
好比要引用模块 math,就能够在文件最开始的地方用 import math 来引入。在调用 math 模块中的函数时,必须这样引用:
模块名.函数名
From…import 语句
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。语法以下:
from modname import name1[, name2[, ... nameN]]
From…import* 语句
把一个模块的全部内容全都导入到当前的命名空间也是可行的,只需使用以下声明:
from modname import *
搜索路径
当你导入一个模块,Python 解析器对模块位置的搜索顺序是:
一、当前目录
二、若是不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每一个目录。
三、若是都找不到,Python会察看默认路径。UNIX下,默认路径通常为/usr/local/lib/python/。
十5、包
包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。
简单来讲,包就是文件夹,但该文件夹下必须存在 __init__.py 文件, 该文件的内容能够为空。__init__.py用于标识当前文件夹是一个包。
考虑一个在 package_runoob 目录下的 runoob1.py、runoob2.py、__init__.py 文件,test.py 为测试调用包的代码,目录结构以下:
test.py
package_runoob
|-- __init__.py
|-- runoob1.py
|-- runoob2.py
package_runoob/runoob1.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
def runoob1():
print "I'm in runoob1"
package_runoob/runoob2.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
def runoob2():
print "I'm in runoob2"
package_runoob/__init__.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
if __name__ == '__main__':
print '做为主程序运行'
else:
print 'package_runoob 初始化'
test.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 导入 Phone 包
from package_runoob.runoob1 import runoob1
from package_runoob.runoob2 import runoob2
runoob1()
runoob2()
以上实例输出结果:
package_runoob 初始化
I'm in runoob1
I'm in runoob2
十6、IO
1.打印到屏幕
print "aaa";
2.读取键盘输入
raw_input函数
str = raw_input("请输入:");
input函数 - input([prompt]) 函数和 raw_input([prompt]) 函数基本相似,可是 input 能够接收一个Python表达式做为输入,并将运算结果返回。
str = input("请输入:");
输入:[x*5 for x in range(2,10,2)]
str: [10, 20, 30, 40]
3.打开和关闭文件
open 函数
file = open(file_name [, access_mode][, buffering])
file_name:file_name变量是一个包含了你要访问的文件名称的字符串值。
access_mode:access_mode决定了打开文件的模式:只读,写入,追加等。全部可取值见以下的彻底列表。这个参数是非强制的,默认文件访问模式为只读(r)。
buffering:若是buffering的值被设为0,就不会有寄存。若是buffering的值取1,访问文件时会寄存行。若是将buffering的值设为大于1的整数,代表了这就是的寄存区的缓冲大小。若是取负值,寄存区的缓冲大小则为系统默认。
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w 打开一个文件只用于写入。若是该文件已存在则将其覆盖。若是该文件不存在,建立新文件。
wb 以二进制格式打开一个文件只用于写入。若是该文件已存在则将其覆盖。若是该文件不存在,建立新文件。
w+ 打开一个文件用于读写。若是该文件已存在则将其覆盖。若是该文件不存在,建立新文件。
wb+ 以二进制格式打开一个文件用于读写。若是该文件已存在则将其覆盖。若是该文件不存在,建立新文件。
a 打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容以后。若是该文件不存在,建立新文件进行写入。
ab 以二进制格式打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容以后。若是该文件不存在,建立新文件进行写入。
a+ 打开一个文件用于读写。若是该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。若是该文件不存在,建立新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。若是该文件不存在,建立新文件用于读写。
file对象属性
file.closed 返回true若是文件已被关闭,不然返回false。
file.mode 返回被打开文件的访问模式。
file.name 返回文件的名称。
file.softspace 若是用print输出后,必须跟一个空格符,则返回false。不然返回true。
关闭文件:
fileObject.close();
写文件:
fileObject.write(string);
读文件:
fileObject.read([count]);
文件随机读写:
tell()方法告诉你文件内的当前位置;换句话说,下一次的读写会发生在文件开头这么多字节以后。
seek(offset [,from])方法改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。
若是from被设为0,这意味着将文件的开头做为移动字节的参考位置。若是设为1,则使用当前的位置做为参考位置。若是它被设为2,那么该文件的末尾将做为参考位置。
重命名文件:
os.rename(current_file_name, new_file_name)
删除文件:
os.remove(file_name)
建立目录:
import os
os.mkdir("newdir")
改变的当前目录:
os.chdir("newdir")
删除目录:
os.rmdir('dirname')
File其余方法:
file.close()
关闭文件。关闭后文件不能再进行读写操做。
file.flush()
刷新文件内部缓冲,直接把内部缓冲区的数据马上写入文件, 而不是被动的等待输出缓冲区写入。
file.fileno()
返回一个整型的文件描述符(file descriptor FD 整型), 能够用在如os模块的read方法等一些底层操做上。
file.isatty()
若是文件链接到一个终端设备返回 True,不然返回 False。
file.next()
返回文件下一行。
file.read([size])
从文件读取指定的字节数,若是未给定或为负则读取全部。
file.readline([size])
读取整行,包括 "\n" 字符。
file.readlines([sizehint])
读取全部行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行, 实际读取值可能比sizhint较大, 由于须要填充缓冲区。
file.seek(offset[, whence])
设置文件当前位置
file.tell()
返回文件当前位置。
file.truncate([size])
截取文件,截取的字节经过size指定,默认为当前文件位置。
file.write(str)
将字符串写入文件,没有返回值。
file.writelines(sequence)
向文件写入一个序列字符串列表,若是须要换行则要本身加入每行的换行符。
十7、异常处理
===========================================
python标准异常
异常名称 描述
BaseException 全部异常的基类
SystemExit 解释器请求退出
KeyboardInterrupt 用户中断执行(一般是输入^C)
Exception 常规错误的基类
StopIteration 迭代器没有更多的值
GeneratorExit 生成器(generator)发生异常来通知退出
StandardError 全部的内建标准异常的基类
ArithmeticError 全部数值计算错误的基类
FloatingPointError 浮点计算错误
OverflowError 数值运算超出最大限制
ZeroDivisionError 除(或取模)零 (全部数据类型)
AssertionError 断言语句失败
AttributeError 对象没有这个属性
EOFError 没有内建输入,到达EOF 标记
EnvironmentError 操做系统错误的基类
IOError 输入/输出操做失败
OSError 操做系统错误
WindowsError 系统调用失败
ImportError 导入模块/对象失败
LookupError 无效数据查询的基类
IndexError 序列中没有此索引(index)
KeyError 映射中没有这个键
MemoryError 内存溢出错误(对于Python 解释器不是致命的)
NameError 未声明/初始化对象 (没有属性)
UnboundLocalError 访问未初始化的本地变量
ReferenceError 弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError 通常的运行时错误
NotImplementedError 还没有实现的方法
SyntaxError Python 语法错误
IndentationError 缩进错误
TabError Tab 和空格混用
SystemError 通常的解释器系统错误
TypeError 对类型无效的操做
ValueError 传入无效的参数
UnicodeError Unicode 相关的错误
UnicodeDecodeError Unicode 解码时的错误
UnicodeEncodeError Unicode 编码时错误
UnicodeTranslateError Unicode 转换时错误
Warning 警告的基类
DeprecationWarning 关于被弃用的特征的警告
FutureWarning 关于构造未来语义会有改变的警告
OverflowWarning 旧的关于自动提高为长整型(long)的警告
PendingDeprecationWarning 关于特性将会被废弃的警告
RuntimeWarning 可疑的运行时行为(runtime behavior)的警告
SyntaxWarning 可疑的语法的警告
UserWarning 用户代码生成的警告
===========================================
try:
<语句> #运行别的代码
except <名字>:
<语句> #若是在try部份引起了'name'异常
except <名字>,<数据>:
<语句> #若是引起了'name'异常,得到附加的数据
else:
<语句> #若是没有异常发生
若是当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就经过整个try语句(除非在处理异常时又引起新的异常)。
若是在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
若是在try子句执行时没有发生异常,python将执行else语句后的语句(若是有else的话),而后控制流经过整个try语句。
try:
fh = open("testfile", "w")
fh.write("这是一个测试文件,用于测试异常!!")
except IOError:
print "Error: 没有找到文件或读取文件失败"
else:
print "内容写入文件成功"
fh.close()
使用except而不带任何异常类型
你能够不带任何异常类型使用except,以下实例:
try:
正常的操做
......................
except:
发生异常,执行这块代码
......................
else:
若是没有异常执行这块代码
try-finally 语句
try-finally 语句不管是否发生异常都将执行最后的代码。
try:
<语句>
finally:
<语句> #退出try时总会执行
异常参数
一个异常能够带上参数,可做为输出的异常信息参数。
你能够经过except语句来捕获异常的参数,以下所示:
try:
正常的操做
......................
except ExceptionType, Argument:
你能够在这输出 Argument 的值...
触发异常
咱们可使用raise语句本身触发异常
raise语法格式以下:
raise [Exception [, args [, traceback]]]
def functionName( level ):
if level < 1:
raise Exception("Invalid level!", level)
# 触发异常后,后面的代码就不会再执行
用户自定义异常
经过建立一个新的异常类,程序能够命名它们本身的异常。异常应该是典型的继承自Exception类,经过直接或间接的方式。
如下为与RuntimeError相关的实例,实例中建立了一个类,基类为RuntimeError,用于在异常触发时输出更多的信息。
在try语句块中,用户自定义的异常后执行except块语句,变量 e 是用于建立Networkerror类的实例。
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
在你定义以上类后,你能够触发该异常,以下所示:
try:
raise Networkerror("Bad hostname")
except Networkerror,e:
print e.args
十8、面向对象
1.建立类
使用class语句来建立一个新类,class以后为类的名称并以冒号结尾,以下实例:
class ClassName:
'类的帮助信息' #类文档字符串
class_suite #类体
类的帮助信息能够经过ClassName.__doc__查看。
class_suite 由类成员,方法,数据属性组成。
实例
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Employee:
'全部员工的基类'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
empCount 变量是一个类变量,它的值将在这个类的全部实例之间共享。你能够在内部类或外部类使用 Employee.empCount 访问。
第一种方法__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当建立了这个类的实例时就会调用该方法
self 表明类的实例,self 在定义类的方法时是必须有的,虽然在调用时没必要传入相应的参数。
self表明类的实例,而非类
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
#self 不是 python 关键字,咱们把他换成 runoob 也是能够正常执行的:
实例
class Test:
def prt(runoob):
print(runoob)
print(runoob.__class__)
t = Test()
t.prt()
建立实例对象
实例化类的对象在其余编程语言中通常用关键字 new,可是在 Python 中并无这个关键字,在python中实例化类的对象似函数的调用。
如下使用类的名称 Employee 来实例化,并经过 __init__ 方法接受参数。
"建立 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"建立 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
访问属性
您可使用点(.)来访问对象的属性。使用以下类的名称访问类变量:
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount
你能够添加,删除,修改类的属性,以下所示:
emp1.age = 7 # 添加一个 'age' 属性
emp1.age = 8 # 修改 'age' 属性
del emp1.age # 删除 'age' 属性
你也可使用如下函数的方式来访问属性:
getattr(obj, name[, default]) : 访问对象的属性。
hasattr(obj,name) : 检查是否存在一个属性。
setattr(obj,name,value) : 设置一个属性。若是属性不存在,会建立一个新属性。
delattr(obj, name) : 删除属性。
hasattr(emp1, 'age') # 若是存在 'age' 属性返回 True。
getattr(emp1, 'age') # 返回 'age' 属性的值
setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8
delattr(empl, 'age') # 删除属性 'age'
Python内置类属性
__dict__ : 类的属性(包含一个字典,由类的数据属性组成)
__doc__ :类的文档字符串
__name__: 类名
__module__: 类定义所在的模块(类的全名是'__main__.className',若是类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
__bases__ : 类的全部父类构成元素(包含了一个由全部父类组成的元组)
实例
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Employee:
'全部员工的基类'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
print "Employee.__doc__:", Employee.__doc__
print "Employee.__name__:", Employee.__name__
print "Employee.__module__:", Employee.__module__
print "Employee.__bases__:", Employee.__bases__
print "Employee.__dict__:", Employee.__dict__
执行以上代码输出结果以下:
Employee.__doc__: 全部员工的基类
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}
*阅读*python对象销毁(垃圾回收)
Python 使用了引用计数这一简单技术来跟踪和回收垃圾。
在 Python 内部记录着全部使用中的对象各有多少引用。
一个内部跟踪变量,称为一个引用计数器。
当对象被建立时, 就建立了一个引用计数, 当这个对象再也不须要时, 也就是说, 这个对象的引用计数变为0 时, 它被垃圾回收。可是回收不是"当即"的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。
a = 40 # 建立对象 <40>
b = a # 增长引用, <40> 的计数
c = [b] # 增长引用. <40> 的计数
del a # 减小引用 <40> 的计数
b = 100 # 减小引用 <40> 的计数
c[0] = -1 # 减小引用 <40> 的计数
垃圾回收机制不只针对引用计数为0的对象,一样也能够处理循环引用的状况。循环引用指的是,两个对象相互引用,可是没有其余变量引用他们。这种状况下,仅使用引用计数是不够的。Python 的垃圾收集器其实是一个引用计数器和一个循环垃圾收集器。做为引用计数的补充, 垃圾收集器也会留心被分配的总量很大(及未经过引用计数销毁的那些)的对象。 在这种状况下, 解释器会暂停下来, 试图清理全部未引用的循环。
实例
析构函数 __del__ ,__del__在对象销毁的时候被调用,当对象再也不被使用时,__del__方法运行:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Point:
def __init__( self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print class_name, "销毁"
pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # 打印对象的id
del pt1
del pt2
del pt3
以上实例运行结果以下:
3083401324 3083401324 3083401324
Point 销毁
类的继承
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是经过继承机制。继承彻底能够理解成类之间的类型和子类型关系。
须要注意的地方:继承语法 class 派生类名(基类名)://... 基类名写在括号里,基本类是在类定义的时候,在元组之中指明的。
在python中继承中的一些特色:
1:在继承中基类的构造(__init__()方法)不会被自动调用,它须要在其派生类的构造中亲自专门调用。
2:在调用基类的方法时,须要加上基类的类名前缀,且须要带上self参数变量。区别于在类中调用普通函数时并不须要带上self参数
3:Python老是首先查找对应类型的方法,若是它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
若是在继承元组中列了一个以上的类,那么它就被称做"多重继承" 。
语法:
派生类的声明,与他们的父类相似,继承的基类列表跟在类名以后,以下所示:
class SubClassName (ParentClass1[, ParentClass2, ...]):
'Optional class documentation string'
class_suite
实例
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Parent: # 定义父类
parentAttr = 100
def __init__(self):
print "调用父类构造函数"
def parentMethod(self):
print '调用父类方法'
def setAttr(self, attr):
Parent.parentAttr = attr
def getAttr(self):
print "父类属性 :", Parent.parentAttr
class Child(Parent): # 定义子类
def __init__(self):
print "调用子类构造方法"
def childMethod(self):
print '调用子类方法 child method'
c = Child() # 实例化子类
c.childMethod() # 调用子类的方法
c.parentMethod() # 调用父类方法
c.setAttr(200) # 再次调用父类的方法
c.getAttr() # 再次调用父类的方法
以上代码执行结果以下:
调用子类构造方法
调用子类方法 child method
调用父类方法
父类属性 : 200
你能够继承多个类
class A: # 定义类 A
.....
class B: # 定义类 B
.....
class C(A, B): # 继承类 A 和 B
.....
你可使用issubclass()或者isinstance()方法来检测。
issubclass() - 布尔函数判断一个类是另外一个类的子类或者子孙类,语法:issubclass(sub,sup)
isinstance(obj, Class) 布尔函数若是obj是Class类的实例对象或者是一个Class子类的实例对象则返回true。
方法重写
若是你的父类方法的功能不能知足你的需求,你能够在子类重写你父类的方法:
实例
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Parent: # 定义父类
def myMethod(self):
print '调用父类方法'
class Child(Parent): # 定义子类
def myMethod(self):
print '调用子类方法'
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
执行以上代码输出结果以下:
调用子类方法
基础重写方法
下表列出了一些通用的功能,你能够在本身的类重写:
1 __init__ ( self [,args...] )
构造函数
简单的调用方法: obj = className(args)
2 __del__( self )
析构方法, 删除一个对象
简单的调用方法 : dell obj
3 __repr__( self )
转化为供解释器读取的形式
简单的调用方法 : repr(obj)
4 __str__( self )
用于将值转化为适于人阅读的形式
简单的调用方法 : str(obj)
5 __cmp__ ( self, x )
对象比较
简单的调用方法 : cmp(obj, x)
运算符重载
Python一样支持运算符重载,实例以下:
实例
#!/usr/bin/python
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2
以上代码执行结果以下所示:
Vector(7,8)
类属性与方法
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.__private_methods
实例
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class JustCounter:
__secretCount = 0 # 私有变量
publicCount = 0 # 公开变量
def count(self):
self.__secretCount += 1
self.publicCount += 1
print self.__secretCount
counter = JustCounter()
counter.count()
counter.count()
print counter.publicCount
print counter.__secretCount # 报错,实例不能访问私有变量
单下划线、双下划线、头尾双下划线说明:
__foo: 双下划线的表示的是私有类型(private)的变量, 只能是容许这个类自己进行访问了。
__foo__: 定义的是特列方法,相似 __init__() 之类的。
使用类相关函数:
type() 判断对象类型
type(123)
type('abc')==types.StringType
isinstance(对象,类) 判断class的类型
isinstance(p,Person)
dir() 得到一个对象的全部属性和方法
dir('ABC')
十9、python基础爬虫之Urllib库
1.入门案例
案例1:访问url读取返回结果
import urllib2
response = urllib2.urlopen("http://www.baidu.com")
print response.read()
说明:
urlopen(url, data, timeout)
第一个参数url即为URL,第二个参数data是访问URL时要传送的数据,第三个timeout是设置超时时间。
第二三个参数是能够不传送的,data默认为空None,timeout默认为 socket._GLOBAL_DEFAULT_TIMEOUT
第一个参数URL是必需要传送的,在这个例子里面咱们传送了百度的URL,执行urlopen方法以后,返回一个response对象,返回信息便保存在这里面
案例2:构造request访问url读取返回结果
import urllib2
request = urllib2.Request("http://www.baidu.com")
response = urllib2.urlopen(request)
print response.read()
运行结果是彻底同样的,只不过中间多了一个request对象,更加面向对象
案例3:Get提交
import urllib
import urllib2
values={'username':'park','password'='123'}
data = urllib.urlencode(values)
url = "http://www.baidu.com" + "?"+data
request = urllib2.Request(url)
response = urllib2.urlopen(request)
print response.read()
案例4:Post提交
import urllib
import urllib2
values = {"username":"park","password":"123"}
data = urllib.urlencode(values)
url = "https://www.baidu.com"
request = urllib2.Request(url,data)
response = urllib2.urlopen(request)
print response.read()
案例5:设置Headers
有些网站不会赞成程序直接用上面的方式进行访问,若是识别有问题,那么站点根本不会响应,因此为了彻底模拟浏览器的工做,咱们须要设置一些Headers 的属性。
import urllib
import urllib2
url = 'http://www.xxxx.com/xxx'
values = {'username' : 'pq', 'password' : 'xxx' }
headers = { 'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' ,
'Referer':'http://www.baidu.com/' }
data = urllib.urlencode(values)
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request)
page = response.read()
案例6:代理设置
urllib2 默认会使用环境变量 http_proxy 来设置 HTTP Proxy。
假如一个网站它会检测某一段时间某个IP 的访问次数,若是访问次数过多,它会禁止你的访问。
因此你能够设置一些代理服务器来帮助你作工做,每隔一段时间换一个代理,以此绕过ip检测。
import urllib2
enable_proxy = True
proxy_handler = urllib2.ProxyHandler({"http" : 'http://some-proxy.com:8080'})
null_proxy_handler = urllib2.ProxyHandler({})
if enable_proxy:
opener = urllib2.build_opener(proxy_handler)
else:
opener = urllib2.build_opener(null_proxy_handler)
urllib2.install_opener(opener)
案例7:超时时间设置
import urllib2
response = urllib2.urlopen('http://www.baidu.com', timeout=10)
或
import urllib2
response = urllib2.urlopen('http://www.baidu.com',data, 10)
案例8:使用DebugLog
能够经过下面的方法把 Debug Log 打开,这样收发包的内容就会在屏幕上打印出来,方便调试
import urllib2
httpHandler = urllib2.HTTPHandler(debuglevel=1)
httpsHandler = urllib2.HTTPSHandler(debuglevel=1)
opener = urllib2.build_opener(httpHandler, httpsHandler)
urllib2.install_opener(opener)
response = urllib2.urlopen('http://www.baidu.com')
案例9:使用cookie
当你获取一个URL你使用一个opener(一个urllib2.OpenerDirector的实例)。在前面,咱们都是使用的默认的opener,也就是urlopen。它是一个特殊的opener,能够理解成opener的一个特殊实例,传入的参数仅仅是url,data,timeout。
若是咱们须要用到Cookie,只用这个opener是不能达到目的的,因此咱们须要建立更通常的opener来实现对Cookie的设置。
import cookielib
import urllib2
#设置保存cookie的文件,同级目录下的cookie.txt
filename = 'cookie.txt'
#声明一个MozillaCookieJar对象实例来保存cookie,以后写入文件
cookie = cookielib.MozillaCookieJar(filename)
#利用urllib2库的HTTPCookieProcessor对象来建立cookie处理器
handler = urllib2.HTTPCookieProcessor(cookie)
#经过handler来构建opener
opener = urllib2.build_opener(handler)
#建立一个请求,原理同urllib2的urlopen
response = opener.open("http://www.baidu.com")
#保存cookie到文件
#ignore_discard的意思是即便cookies将被丢弃也将它保存下来,ignore_expires的意思是若是在该文件中cookies已经存在,则覆盖原文件写入,在这里,咱们将这两个所有设置为True。
cookie.save(ignore_discard=True, ignore_expires=True)
import cookielib
import urllib2
#建立MozillaCookieJar实例对象
cookie = cookielib.MozillaCookieJar()
#从文件中读取cookie内容到变量
cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
#建立请求的request
req = urllib2.Request("http://www.baidu.com")
#利用urllib2的build_opener方法建立一个opener
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
response = opener.open(req)
print response.read()
3、Python爬虫框架
基于Python的爬虫框架有不少,比较知名的是Scrapy 和PySpider。
pyspider上手更简单,操做更加简便,由于它增长了 WEB 界面,写爬虫迅速,集成了phantomjs,能够用来抓取js渲染的页面。
Scrapy自定义程度高,比 PySpider更底层一些,适合学习研究,须要学习的相关知识多,不过本身拿来研究分布式和多线程等等是很是合适的。
咱们主要介绍pyspider
1.pyspider安装配置
(1)安装pip
pip是python的包管理工具 相似RedHat里面的yum
访问https://pypi.python.org/pypi/pip#downloads
下载pip安装包
解压pip-9.0.1.tar.gz
在该目录下执行 setup.py install
将python安装目录下的Scripts配置到PATH环境变量
(2)安装phantomjs
访问http://phantomjs.org/download.html
下载对应版本phantomjs
解压phantomjs-2.1.1-windows.zip
将其bin目录配置到PATH环境变量中
(3)使用pip安装pyspider
pip install pyspider
(4)运行pyspider
pyspider all
(5)经过浏览器访问pyspider
http://localhost:5000
2.PySpider语法
http://docs.pyspider.org/en/latest/
略
3.PySpider案例
http://cuiqingcai.com/2652.html
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2017-11-17 10:28:34
# Project: MM_TT
from pyspider.libs.base_handler import *
import os
import random
class Handler(BaseHandler):
crawl_config = {
}
baseDir = 'E:\\tbmm';
def __init__(self):
pass
@every(minutes=24 * 60)
def on_start(self):
for x in range(30):
self.crawl('https://mm.taobao.com/json/request_top_list.htm?page='+str(x+1), callback=self.index_page,validate_cert=False)
@config(age=10 * 24 * 60 * 60)
def index_page(self, response):
for each in response.doc('.lady-name').items():
self.crawl(each.attr.href,callback=self.mm_page,validate_cert=False,fetch_type='js')
@config(age=10 * 24 * 60 * 60)
def mm_page(self, response):
self.crawl("https:"+response.doc('.mm-p-domain-info li > span').text(),callback=self.mm_detail_page,validate_cert=False,fetch_type='js')
@config(age=10 * 24 * 60 * 60)
def mm_detail_page(self, response):
#获取mm名字 建立对应文件夹
mm_name = response.doc('.mm-p-model-info-left-top dd>a').text().encode("gbk")
if not os.path.exists(self.baseDir+'\\'+mm_name):
os.mkdir(self.baseDir+'\\'+mm_name)
#建立desc.txt写出描述信息
mm_desc = response.doc('.mm-aixiu-content').text().encode("gbk")
f = open(self.baseDir+'\\'+mm_name+"\\desc.txt",'w')
f.write(mm_desc)
f.flush()
f.close()
#获取mm全部图片地址 加入爬取
mm_imgs = response.doc('.mm-aixiu-content > div > img').items()
for mm_img in mm_imgs:
self.crawl(mm_img.attr.src, callback=self.download_img_page,validate_cert=False,save={'imgdir':self.baseDir+'\\'+mm_name+'\\'+mm_img.attr.src.split("/")[-1]})
@config(age=10 * 24 * 60 * 60)
def download_img_page(self, response):
imgcontent=response.content
imgfile=open(response.save['imgdir'],"wb")
imgfile.write(imgcontent)
imgfile.flush()
imgfile.close()
4.PySpider案例
https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2018-07-28 16:28:24
# Project: DBDY
from pyspider.libs.base_handler import *
import json
import os
class Handler(BaseHandler):
base_dir="D:\\DBDY"
@every(minutes=24 * 60)
def on_start(self):
self.crawl('https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=rank&page_limit=100&page_start=0',validate_cert=False, callback=self.mv_j_page)
@config(age=10 * 24 * 60 * 60) def mv_j_page(self, response): jdata = json.loads(response.text) for each in jdata["subjects"]: self.crawl(each["url"],validate_cert=False, callback=self.mv_detail_page) @config(age=10 * 24 * 60 * 60) def mv_detail_page(self, response): #获取电影标题 title = response.doc("h1 > span").text().encode("gbk") #建立以电影标题为名字的文件夹 if not os.path.exists(self.base_dir+"\\"+title): os.mkdir(self.base_dir+"\\"+title) #获取电影的描述信息 info = response.doc("#info").text().encode("gbk") #将电影描述信息写出到电影对应的文件夹中 f = open(self.base_dir+"\\"+title+"\\info.txt","w+"); f.write(info) f.flush() f.close() #获得当前电影对应的图片页面 self.crawl(response.doc(".related-pic .pl :nth-child(3)").attr.href,validate_cert=False, callback=self.mv_all_photos_page,save={"mv_dir":self.base_dir+"\\"+title}) @config(age=10 * 24 * 60 * 60) def mv_all_photos_page(self, response): for each in response.doc(".article li a").items(): self.crawl(each.attr.href,validate_cert=False, callback=self.mv_detail_photo_page,save=response.save) @config(age=10 * 24 * 60 * 60) def mv_detail_photo_page(self, response): self.crawl(response.doc(".mainphoto > img").attr.src,validate_cert=False, callback=self.download_photo_page,save={"img_dir":response.save["mv_dir"]+"\\"+response.doc(".mainphoto > img").attr.src.split("/")[-1]}) @config(age=10 * 24 * 60 * 60) def download_photo_page(self, response): img_data = response.content f = open(response.save["img_dir"],"wb"); f.write(img_data) f.flush() f.close()