1 python基础知识
1.1 简介
Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。支持多种平台。下载安装https://www.python.org/,在系统环境变量path中加入python的安装目录。有三种编写方式
(1) 交互式解释器。可以在cmd输入python进入交互式运行状态,输入代码。
(2) 命令行脚本。在文本编辑器汇总编写name.py脚本,在命令行执行python name.py。
(3) 在集成开发工具和环境中编写和运行, 通常有pycharm。下载地址:https://www.jetbrains.com/pycharm/download/,需要破解。
1.2 中文编码
为了支持中文,需要在脚本前面加上# -*- coding: UTF-8 -*- 或者 # coding=utf-8设置编码格式。如下
#!/usr/bin/python
# -*- coding: UTF-8 -*-
pycharm设置在file->setting->editor->file Encoding
1.3 python的基础语法
1.3.1 文件包含和引入
python是文件pythonfilename.py形式组织代码,在文件中开头会有引入其他文件,可以直接用import 文件名称的形式来引入其它文件,例如将a.py引入到b.py。可以在b.py中加入 import a。也可以只引入a中的函数func,from a import func。就可以直接b中调用a的函数。
1.3.2 python中的下划线_
(1) 以单下划线开头。 _foo 的代表不能直接访问的类属性,相当于java的protect属性,需通过类提供的接口进行访问,不能用 from xxx import * 而导入。
(2) 双下划线开头的 __foo 代表类的私有成员,相当于java的private属性。
(3) 双下划线开头和结尾的 __foo__ 代表 Python 里特殊方法专用的标识,如 __init__() 代表类的构造函数。
1.3.3 python的范围作用域划分
Python 的代码块不使用大括号 {} 来划分范围,而是用缩进来判断作用域范围。而且缩进方式要严格一致,不能用tab和空格混用。
if True:
print ("True")
else:
print ("False")
符号连接多上显示。[], {} 或 () 括号就不需要使用多行连接符。
days = ['Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday']
1.3.4 python注释
(1) 单行注释#
(2) 多行注释用三个单引号或者双引号’’’ ’’’或者””” ”””
1.4 python变量类型
python的变量定义不是用具体的类型去声明变量,java是 double a=10.0;python直接是a=10.0;python会直接根据赋值去判断类型。
1.4.1 number数字类型
(1)数据类型定义
1) 整型 a=10
2) 长整型 a=10L或a=10l
3) 浮点型 a=10.0
4) complex复数 a=1+3.14j或a=1+3.14J
(2)python数学函数
Python 中数学运算常用的函数基本都在 math 模块、cmath 模块中,引入模块,然后调用。
函数 |
返回值 ( 描述 ) |
返回数字的绝对值,如abs(-10) 返回 10 |
|
返回数字的上入整数,如math.ceil(4.1) 返回 5 |
|
如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1 |
|
返回e的x次幂(ex),如math.exp(1) 返回2.718281828459045 |
|
返回数字的绝对值,如math.fabs(-10) 返回10.0 |
|
返回数字的下舍整数,如math.floor(4.9)返回 4 |
|
如math.log(math.e)返回1.0,math.log(100,10)返回2.0 |
|
返回以10为基数的x的对数,如math.log10(100)返回 2.0 |
|
返回给定参数的最大值,参数可以为序列。 |
|
返回给定参数的最小值,参数可以为序列。 |
|
返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。 |
|
x**y 运算后的值。 |
|
返回浮点数x的四舍五入值,如给出n值,则代表舍入到小数点后的位数。 |
|
返回数字x的平方根 |
(3) python随机函数
函数 |
描述 |
从序列的元素中随机挑选一个元素,比如random.choice(range(10)),从0到9中随机挑选一个整数。 |
|
从指定范围内,按指定基数递增的集合中获取一个随机数,基数默认值为 1 |
|
随机生成下一个实数,它在[0,1)范围内。 |
|
改变随机数生成器的种子seed。如果你不了解其原理,你不必特别去设定seed,Python会帮你选择seed。 |
|
将序列的所有元素随机排序 |
|
随机生成下一个实数,它在[x,y]范围内。 |
(4) python三角函数
函数 |
描述 |
返回x的反余弦弧度值。 |
|
返回x的反正弦弧度值。 |
|
返回x的反正切弧度值。 |
|
返回给定的 X 及 Y 坐标值的反正切值。 |
|
返回x的弧度的余弦值。 |
|
返回欧几里德范数 sqrt(x*x + y*y)。 |
|
返回的x弧度的正弦值。 |
|
返回x弧度的正切值。 |
|
将弧度转换为角度,如degrees(math.pi/2) , 返回90.0 |
|
将角度转换为弧度 |
1.4.2 python字符串
(1)字符串定义
字符串定义a=”RUNOOB”
(2)字符串截取
字符串按照索引值访问,a[0]。可以通过a[indexstart,indexend]的方式截取包含indexstart,但是不包含indexend的字符串。字符串截取从左往右0开始计数,从右往左从-1开始计数。例如a[1,3]是“UN”,a[-1,-3]是“BO”。
str = 'Hello World!'
print str # 输出完整字符串Hello World!
print str[0] # 输出字符串中的第一个字符H
print str[2:5] # 输出字符串中第三个至第六个之间的字符串llo
print str[2:] # 输出从第三个字符开始的字符串llo World!
print str * 2 # 输出字符串两次Hello World!Hello World!
print str + "TEST" # 输出连接的字符串Hello World!TEST
(3)字符串按步长截取
Python 列表截取可以接收第三个参数,参数作用是截取的步长,以下实例在索引 1 到索引 4 的位置并设置为步长为 2(间隔一个位置)来截取字符串:
(4)字符串操作符
操作符 |
描述 |
实例 |
+ |
字符串连接 |
>>>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' ' >>> print R' ' |
(5) 字符串格式化
print "My name is %s and weight is %d kg!" % ('Zara', 21)
符 号 |
描述 |
%c |
格式化字符及其ASCII码 |
%s |
格式化字符串 |
%d |
格式化整数 |
%u |
格式化无符号整型 |
%o |
格式化无符号八进制数 |
%x |
格式化无符号十六进制数 |
%X |
格式化无符号十六进制数(大写) |
%f |
格式化浮点数字,可指定小数点后的精度 |
%e |
用科学计数法格式化浮点数 |
%E |
作用同%e,用科学计数法格式化浮点数 |
%g |
%f和%e的简写 |
%G |
%F 和 %E 的简写 |
%p |
用十六进制数格式化变量的地址 |
1.4.3 python tuple元组
(1) 元组定义a=(1,2,3),一次初始化,只读不能修改。
(2) 访问,用过索引访问,a[0]。
(3) 连接,tup3=tup2+tup1
(4) 删除,tuple不支持删除元素,只支持元组整个删除。del a正确,del a[1]报错。
(5) 截取,a[1:]为(2,3)
(6) 遍历,for x in a: print x,
1.4.4 python list列表
(1) 列表定义a=[1,2,3],可以通过a[0]去修改,用append在末尾添加,相当于java数组。
(2) 末尾添加,a.append(4),a变成[1,2,3,4]
(3) 删除元素,del a[2],a变成[1,2,4],按照索引删除,索引从0开始。
(4) 遍历 for x in a:print x
(5) 截取 b=a[2:3],b变成 [3],同样是包含start,不包含end索引。
列表list的函数方法
Python包含以下函数:
序号 |
函数 |
1 |
cmp(list1, list2) |
2 |
len(list) |
3 |
max(list) |
4 |
min(list) |
5 |
list(seq) |
Python包含以下方法:
序号 |
方法 |
1 |
list.append(obj) |
2 |
list.count(obj) |
3 |
list.extend(seq) |
4 |
list.index(obj) |
5 |
list.insert(index, obj) |
6 |
list.pop([index=-1]) |
7 |
list.remove(obj) |
8 |
list.reverse() |
9 |
1.4.5 python dict字典
(1) 字典定义,a={‘m’:1,’n’:2,’t’:3},有点像json格式,相当于java的map,可以按键读写。
(2) 访问修改,a[‘m’]=2。
(3) 删除del a[‘m’],清空a.clear(),整个删除del a
(4) 值类型,字典中的值的类型可以不一样
字典的操作函数
Python字典包含了以下内置函数:
序号 |
函数及描述 |
1 |
cmp(dict1, dict2) |
2 |
len(dict) |
3 |
str(dict) |
4 |
type(variable) |
Python字典包含了以下内置方法:
序号 |
函数及描述 |
1 |
dict.clear() |
2 |
dict.copy() |
3 |
dict.fromkeys(seq[, val]) |
4 |
dict.get(key, default=None) |
5 |
dict.has_key(key) |
6 |
dict.items() |
7 |
dict.keys() |
8 |
dict.setdefault(key,
default=None) |
9 |
dict.update(dict2) |
10 |
dict.values() |
11 |
pop(key[,default]) |
12 |
popitem() |
1.4.6 强制类型转换
函数 |
描述 |
将x转换为一个整数 |
|
将x转换为一个长整数 |
|
将x转换到一个浮点数 |
|
创建一个复数 |
|
将对象 x 转换为字符串 |
|
将对象 x 转换为表达式字符串 |
|
用来计算在字符串中的有效Python表达式,并返回一个对象 |
|
将序列 s 转换为一个元组 |
|
将序列 s 转换为一个列表 |
|
转换为可变集合 |
|
创建一个字典。d 必须是一个序列 (key,value)元组。 |
|
转换为不可变集合 |
|
将一个整数转换为一个字符 |
|
将一个整数转换为Unicode字符 |
|
将一个字符转换为它的整数值 |
|
将一个整数转换为一个十六进制字符串 |
|
将一个整数转换为一个八进制字符串 |
1.5 python运算符
与java和C++的运算符操作基本一致,主要描述不同之处。
1.5.1 算术运算符
** |
幂 - 返回x的y次幂 |
a**b 为10的20次方, 输出结果 100000000000000000000 |
// |
取整除 - 返回商的整数部分(向下取整) |
>>> 9//2 4 >>> -9//2 -5 |
1.5.2 逻辑运算符
逻辑运算符不采用&&、||、~,而是用英文单词。
算符 |
逻辑表达式 |
描述 |
实例 |
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 |
1.5.3 成员运算符
判断一个成员是否在list中
运算符 |
描述 |
实例 |
in |
如果在指定的序列中找到值返回 True,否则返回 False。 |
x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 |
not in |
如果在指定的序列中没有找到值返回 True,否则返回 False。 |
x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 |
a=2
list = [1, 2, 3, 4, 5 ];
if(a in list) #true
1.5.4 身份运算符与==比较
判断两个变量是否有相同的地址,相当于x is y 类似于id(x)==id(y),id是取地址的意思,地址是按照值去判断,相同的值有相同的地址,无论是num和元组group、列表list、字典dict,只要值相同,id就相同,唯一另外的情况是a=[1,2,3],b=a[:],这样是重新申请内存,a[1] is not b[1]。==只要值相同都是相等的。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
a = 20
b = 20
print("1 num to num")
print(id(a))
print(id(b))
print (a is b)
"""
1 num to num
140717616758432
140717616758432
True
"""
a=30
print("2 num diff to num")
print(id(a))
print(id(b))
print (a is b)
"""
2 num diff to num
140717616758752
140717616758432
False
"""
a=20
print("3 num same to num")
print(id(a))
print(id(b))
print (a is b)
"""
3 num same to num
140717616758432
140717616758432
True
"""
a=[10,20,30]
print("4 list to num")
print(id(a))
print(id(b))
print (a[1] is b)
"""
4 list to num
1995189525384
140717616758432
True
"""
b=a[:]
print("5 list copy to list")
print(id(a))
print(id(b))
print (a is b)
"""
5 list copy to list
1995189525384
1995189525896
False
"""
b=(10,20,30)
print("6 groud to list")
print(id(a))
print(id(b))
print (a[1] is b[1])
"""
6 groud to list
1995189525384
1995189464104
True
"""
b={'m':10,'n':20,'t':30}
print("7 list to dict ")
print(id(a))
print(id(b))
print (a[1] is b['n'])
"""
7 list to dict
1995189525384
1995189527640
True
"""
b=a
print("8 list to list ")
print(id(a))
print(id(b))
print (a is b)
"""
8 list to list
1995189525384
1995189525384
True
"""
1.6 python条件语句
python的条件语句与java略有不同,if elif else,采用冒号和缩进来限制范围。
num = 5
if num == 3: # 判断num的值
print 'boss'
elif num == 2:
print 'user'
elif num == 1:
print 'worker'
elif num < 0: # 值小于零时输出
print 'error'
else:
print 'roadman' # 条件均不成立时输出
if ( var == 100 ) : print "变量 var 的值为100"#一行显示简单语句
1.7 python循环语句
只有while和for循环,可以嵌套,没有do while循环,while和for后面还可以加else。循环控制语句除了有break和continue,多了一个pass空语句。还是采用冒号:和缩进来限制范围。
(1)while实例
while count < 5:
print count, " is less than 5"
count = count + 1
else:
print count, " is not less than 5"
输出结果:
0 is less than 5
1 is less than 5
2 is less than 5
3 is less than 5
4 is less than 5
5 is not less than 5
(2)for实例
for循环一般用于list,字典dict的遍历,也可以加else
fruits = ['banana', 'apple', 'mango']
for index in range(len(fruits)):
print '当前水果 :', fruits[index]
print "Good bye!"
(6) 只要一条语句的简单语组
while (flag): print 'Given flag is really true!'
(7) 循环嵌套
while expression:
while expression:
statement(s)
statement(s)
1.8 Python pass 语句
pass是一个空语句,一个占位符。 作用是定义一个函数,没想好内容时,可以先pass,空函数会报错,加了pass就不会报错,先做其他的,想好函数定义在来填写函数内容
在 Python 中有时候会看到一个 def 函数:
def sample(n_samples):
pass
1.9 Python 日期calendar和时间time
1.9.1 时间time
(1) 获取时间戳,单位秒
import time;
# 引入time模块
ticks = time.time()
(2) 获取本地时间结构体
import time
localtime = time.localtime(time.time())
print("本地时间为 :", localtime)
输出:
本地时间为 :time.struct_time(tm_year=2020, tm_mon=3, tm_mday=15, tm_hour=19, tm_min=34, tm_sec=17, tm_wday=6, tm_yday=75, tm_isdst=0)
(3) 简单格式输出时间
localtime = time.asctime( time.localtime(time.time()) )
print ("本地时间为 :", localtime)
输出
本地时间为 : Sun Mar 15 19:37:56 2020
(4) 自定义格式输出时间
# 格式化成2016-03-20 11:45:39形式
print time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
python中时间日期格式化符号:
- %y 两位数的年份表示(00-99)
- %Y 四位数的年份表示(000-9999)
- %m 月份(01-12)
- %d 月内中的一天(0-31)
- %H 24小时制小时数(0-23)
- %I 12小时制小时数(01-12)
- %M 分钟数(00=59)
- %S 秒(00-59)
- %a 本地简化星期名称
- %A 本地完整星期名称
- %b 本地简化的月份名称
- %B 本地完整的月份名称
- %c 本地相应的日期表示和时间表示
- %j 年内的一天(001-366)
- %p 本地A.M.或P.M.的等价符
- %U 一年中的星期数(00-53)星期天为星期的开始
- %w 星期(0-6),星期天为星期的开始
- %W 一年中的星期数(00-53)星期一为星期的开始
- %x 本地相应的日期表示
- %X 本地相应的时间表示
- %Z 当前时区的名称
- %% %号本身
1.9.2 日期calendar
import calendar
cal = calendar.month(2020, 3)
print ("以下输出2016年1月份的日历:")
print (cal)
time.sleep(secs)
推迟调用线程的运行,secs指秒数。
time.clock( )
用以浮点数计算的秒数返回当前的CPU时间。用来衡量不同程序的耗时,比time.time()更有用。
time.time( )
返回当前时间的时间戳(1970纪元后经过的浮点秒数)。
1.10 Python 函数
1.10.1 函数定义
python函数定义以def开始,函数名称,入参,第二行专门留个字符串做函数说明。
def printme( str ):
"打印传入的字符串到标准显示设备上"
print str
return
1.10.2 参数传递
(1)参数按值传递和按引用传递
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
- 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
- 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
- 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
- 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响。参数传入la[2],也不会修改la[2]的值。
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
(2)参数传递的对应关系
1)必备参数,函数定了参数,就要传入什么参数printme("My string")
2)关键字参数,多个参数用函数参数名称实现对应传递,顺序可以不和函数定义一致。printinfo( age=50, name="miki" )
3)默认参数,def printinfo( name, age = 35 ):
4)不定长参数,函数后面不确定要传入几个参数
def printinfo( arg1, *vartuple ):
"打印任何传入的参数"
print "输出: "
print arg1
for var in vartuple:
print var
return
# 调用printinfo 函数
printinfo( 10 )
printinfo( 70, 60, 50 )
1.10.3 匿名函数
用一个lambda表达式来声明匿名函数,不能访问全局命名空间的参数。
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
1.10.4 全局变量和局部变量
(1)定义
全局变量:定义在函数外的拥有全局作用域。而全局变量可以在整个程序范围内访问。
局部变量:定义在函数内部的变量拥有一个局部作用域,只能在其被声明的函数内部访问,
(2)与全局变量重名局部变量
函数内部如果定义局部变量和全局变量重名,则表示的是局部变量。
total = 0 # 这是一个全局变量
# 可写函数说明
def sum(arg1, arg2):
# 返回2个参数的和."
#total=total+1 #这一行不注释会报错,后面一个total是未知变量
total = arg1 + arg2 # total在这里是局部变量.
print("函数内是局部变量 : ", total)
return total
# 调用sum函数
sum(10, 20)
print("函数外是全局变量 : ", total)
(3)显示声明函数内部使用全局变量
total = 0 # 这是一个全局变量
# 可写函数说明
def sum(arg1, arg2):
# 返回2个参数的和."
global total#声明在函数作用域内使用全局变量
total = total + 1
print("函数内是局部变量 : ", total)
total = arg1 + arg2 # total在这里是局部变量.
print("函数内是局部变量 : ", total)
return total
# 调用sum函数
sum(10, 20)
print("函数外是全局变量 : ", total)
1.11 python模块和包
1.11.1 python的模块
模块是一个file.py文件,文件中可以定义类和函数和变量。
(1)引入模块
import math 或者from math import *
(2)引入模块中的函数
import math.abs 或者 from math import abs
1.11.2 python的包
包是一个分层次的文件夹,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。文件夹内必须存在__init__.py文件,内容可以为空,这个文件标识这个文件夹是一个包。__init__.py相当于初始化函数,咋调用包时,都会执行__init__.py里面的代码。引入包package_runoob中的模块中的函数方法如下
包名 文件名 函数名
from package_runoob.runoob1 import runoob1
from package_runoob.runoob2 import runoob2
1.12 python文件IO
1.13 python多线程
python线程有两种方式,可以thread模块的start_new_thread()函数来参数新线程。
(1)thread模块的start_new_thread()
线程使用格式
def function(a,b):
print(a)
thread.start_new_thread ( function, args[, kwargs] )
参数说明:
function - 线程函数。
args - 传递给线程函数的参数,他必须是个tuple类型。
kwargs - 可选参数。
线程使用实例
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import thread
import time
# 为线程定义一个函数
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print "%s: %s" % ( threadName, time.ctime(time.time()) )
# 创建两个线程
try:
thread.start_new_thread( print_time, ("Thread-1", 2, ) )
thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
print "Error: unable to start thread"
while 1:
pass
输出结果
Thread-1: Thu Jan 22 15:42:17 2009
Thread-1: Thu Jan 22 15:42:19 2009
Thread-2: Thu Jan 22 15:42:19 2009
Thread-1: Thu Jan 22 15:42:21 2009
Thread-2: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:25 2009
Thread-2: Thu Jan 22 15:42:27 2009
Thread-2: Thu Jan 22 15:42:31 2009
Thread-2: Thu Jan 22 15:42:35 2009
(2)继承threading.Thread 类重写__init__方法和run方法:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import threading
import time
exitFlag = 0
class myThread (threading.Thread): #继承父类threading.Thread
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self): #把要执行的代码写到run函数里面 线程在创建后会直接运行run函数
print "Starting " + self.name
print_time(self.name, self.counter, 5)
print "Exiting " + self.name
def print_time(threadName, delay, counter):
while counter:
if exitFlag:
(threading.Thread).exit()
time.sleep(delay)
print "%s: %s" % (threadName, time.ctime(time.time()))
counter -= 1
# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# 开启线程
thread1.start()
thread2.start()
print "Exiting Main Thread"
(3)线程同步
通过threadLock = threading.Lock(),获取线程锁,然后通threadLock.acquire()加锁,通过threadLock.release()释放锁。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import threading
import time
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print "Starting " + self.name
# 获得锁,成功获得锁定后返回True
# 可选的timeout参数不填时将一直阻塞直到获得锁定
# 否则超时后将返回False
threadLock.acquire()
print_time(self.name, self.counter, 3)
# 释放锁
threadLock.release()
def print_time(threadName, delay, counter):
while counter:
time.sleep(delay)
print "%s: %s" % (threadName, time.ctime(time.time()))
counter -= 1
threadLock = threading.Lock()
threads = []
# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# 开启新线程
thread1.start()
thread2.start()
# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)
# 等待所有线程完成
for t in threads:
t.join()
print "Exiting Main Thread"
1.14 queue队列
Python的Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用。
1.14.1 队列queue类型
1)先进先出FIFO ,q=queue.queue();
2)后进先出LIFO, q = queue.LifoQueue();
3)优先级队列PriorityQueue,q = queue.PriorityQueue() q.put((2, '2')),优先级1最高;
1.14.2 阻塞和不阻塞
阻塞情况:当队列满了之后,put 就会阻塞,一直等待队列不再满时向里面添加数据。当队列空了之后,get 就会阻塞,一直等待队列中有数据后再获取数据。
不阻塞情况:get为空时返回_queue.Empty,put满队列时返回queue.Full。put_nowait() 或 put(block=False),get_nowait() 或 get(block=False)。
Queue.empty()/Queue.full() 用于判断队列是否为空、满
Queue.qsize() 用于获取队列中大致的数据量,在多线程的情况下不可靠
join 会在队列存在未完成任务时阻塞,等待队列无未完成任务,需要配合
task_done执行一次 put 会让未完成任务 +1 ,但是执行 get 并不会让未完成任务 -1 ,需要使用 task_done 让未完成任务 -1 。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import Queue
import threading
import time
exitFlag = 0
class myThread (threading.Thread):
def __init__(self, threadID, name, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.q = q
def run(self):
print "Starting " + self.name
process_data(self.name, self.q)
print "Exiting " + self.name
def process_data(threadName, q):
while not exitFlag:
queueLock.acquire()
if not workQueue.empty():
data = q.get()
queueLock.release()
print "%s processing %s" % (threadName, data)
else:
queueLock.release()
time.sleep(1)
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1
# 创建新线程
for tName in threadList:
thread = myThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# 填充队列
queueLock.acquire()
for word in nameList:
workQueue.put(word)
queueLock.release()
# 等待队列清空
while not workQueue.empty():
pass
# 通知线程是时候退出
exitFlag = 1
# 等待所有线程完成
for t in threads:
t.join()
print "Exiting Main Thread"
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: