#使用import语句引入标准库中的模块
import sys
# 包含命令行参数的列表
print(sys.argv)
# 自动查找所需模块的路径列表
print(sys.path)
标准库 | 说明 |
---|---|
builtins | 内建函数默认加载 |
math | 数学库 |
random | 生成随机数 |
time | 时间 |
datetime | 日期和时间 |
calendar | 日历 |
hashlib | 加密算法 |
copy | 拷贝 |
functools | 常用的工具 |
os | 操作系统接口 |
re | 字符串正则匹配 |
sys | Python自身的运行环境 |
multiprocessing | 多进程 |
threading | 多线程 |
json | 编码和解码 JSON 对象 |
logging | 记录日志,调试 |
import语句
from……import语句
from……import 星语句
from 包.模块 import 对象 as 别名
概念:每个模块都有一个__name__属性,当其值为"main"时,表名该模块自身在运行,否则是被当做模块引入,此时值为模块的名
作用:模块就是一个可执行的python文件,一个模块被另一个模块引入,想让模块中的某一段程序不执行,我们可以使用__name__属性来隐藏该段代码,当自身执行时在执行该段代码
以后一般程序的起始位置都是从__name__=="main"处开始
物理环境安装步骤:
1.在终端中输入命令:pip -V 【检查版本,这个步骤在安装Python环境的时候如果勾选了Add path选项,则已自动安装】
2.安装第三方模块:pip install pillow 【pillow为一个图形处理的第三方模块,需要联网下载】
如果此步出错,则执行命令 python -m pip install --upgrade
https://pillow.readthedocs.io/en/latest/reference/ImageDraw.html#functions
3,.如果不使用第三方模块,则可以执行命令:pip uninstall pillow ,卸载第三方模块
# time()
# 返回当前时间的时间戳
t1 = time.time()
print(t1)
#1563612216.2735271
#gmtime()
#将时间戳格式转为UTC时间元组格式,接收一个浮点型时间戳作为参数,如果不传默认使用当前时间戳
t2 = time.gmtime()
print(t2) #time.struct_time(tm_year=2019, tm_mon=7, tm_mday=20, tm_hour=8, tm_min=43, tm_sec=36, tm_wday=5, tm_yday=201, tm_isdst=0)
print(type(t2)) #
# localtime()
# 将时间戳转为本地时间元组格式,接收一个浮点型时间戳作为参数,如果不传默认使用当前时间戳
t3 = time.localtime()
print(t3) #time.struct_time(tm_year=2019, tm_mon=7, tm_mday=20, tm_hour=16, tm_min=43, tm_sec=36, tm_wday=5, tm_yday=201, tm_isdst=0)
print(type(t3)) #
#mktime()
#将本地时间元组转为时间戳,接收一个时间元组
t4 = time.mktime(t3)
print(t4) #1563612216.0
print(type(t4)) #
#asctime()
# 将时间元组格式转为字符串形式,接收一个时间元组,默认值为localtime的时间元组
t5 = time.asctime(t3)
print(t5) #Sat Jul 20 16:43:36 2019
print(type(t5)) #
#ctime()
#将时间戳转为字符串,接收一个时间戳,默认为当前时间戳
t6 = time.ctime()
print(t6) #Sat Jul 20 16:43:36 2019
#
print(type(t6))
#strftime()
#将时间元组以指定的格式转为字符串形式,接收一个字符串格式化串,时间元组(默认本地时间元组)
t7 = time.strftime("%Y-%m-%d %X", t3)
print(t7) #2019-07-20 16:43:36
#strptime()
#将指定格式的时间字符串解析为时间元组,是strftime逆过程,两个参数要对应
t8 = time.strptime("2018-02-23 12:34:45", "%Y-%m-%d %X")
print(t8) #time.struct_time(tm_year=2018, tm_mon=2, tm_mday=23, tm_hour=12, tm_min=34, tm_sec=45, tm_wday=4, tm_yday=54, tm_isdst=-1)
#sleep()
# 延迟一个时间段,接收整型或者浮点型,以秒为单位
#clock()
# 返回当前程序执行的时间,在Unix、linux系统中始终返回全部运行时间,而windows从第二次开始都是以第一次调用此函数的时间戳为基准,而不是以程序开始的时间戳为基准
# tzset()
# 改变时区
datetime 比 time 模块高级了不少,可以理解为datetime基于time进行了封装,提供了更实用的接口函数
模块中的类:
time 只关注时间
date 只关注日期
datetime 同时关注日期和时间
timedelta 主要用于计算时间跨度
tzinfo 时区相关
#获取当前时间
t1 = datetime.datetime.now()
print(t1)
#2019-07-20 17:00:50.372674
#
print(type(t1))
#获取指定时间
t2 = datetime.datetime(2001, 10, 1, 8, 8, 8, 0)
print(t2)
#2001-10-01 08:08:08
<class 'datetime.datetime'>
print(type(t2))
# 将时间转为字符串
t3 = t2.strftime("%y-%m-%d %X")
print(t3)
#01-10-01 08:08:08
#
print(type(t3))
#将格式化的字符串转为datetime对象
t4 = datetime.datetime.strptime(t3, "%y-%m-%d %X")
print(t4)
print(type(t4))
#2001-10-01 08:08:08
#
#计算时间差
t5 = datetime.datetime(2001, 10, 1, 8, 8, 8, 0)
t6 = datetime.datetime(2001, 9, 29, 7, 8, 1, 0)
t7 = t5 - t6
print(t7)
print(type(t7))
#2 days, 1:00:07
#
#间隔天数
print(t7.days)
#2
# 除去间隔天数以外的间隔秒数
print(t7.seconds)
#3607
#日历模块
import calendar
#返回指定年的某月
print(calendar.month(2019,3))
'''
March 2019
Mo Tu We Th Fr Sa Su
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
'''
#返回指定年的日历
print(calendar.calendar(2018))
#判断某一年是否是闰年
print(calendar.isleap(2001)) #False
print(calendar.leapdays(2000,2020)) #5
#返回某个月的weekday的第一天和这个月的所有天数
print(calendar.monthrange(2019, 8)) #(3, 31)
# 返回某个月以一周为周期的元素序列
print(calendar.monthcalendar(2019, 8)) #[[0, 0, 0, 1, 2, 3, 4], [5, 6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17, 18], [19, 20, 21, 22, 23, 24, 25], [26, 27, 28, 29, 30, 31, 0]]
print(type(calendar.monthcalendar(2019, 8)))
#当前日期表示的星期数
print(calendar.weekday(2019,7,20)) #5
概述:
是128位的全局唯一标识符,通常由32字节的字符串表示,它可以保证时间和空间的唯一性,页称为GUID
原理:
通过mac地址、时间戳、命名空间、随机数、伪随机数来保证产生的id的唯一性
作用:
随机生成字符串,当成账号、token、订单号等使用(要求不相同字符串)
算法:
1、uuid1()基于时间戳
由mac地址、当前时间戳、随机数字,可以保证全球范围内的唯一性,但是用于mac地址的使用时带来安全问题,局域网中可以使用ip代替mac
2、uuid2()基于分布式计算环境DCE
算法和uuid1相同,不同的是把时间戳的前四位换位POSIX的UID,实际当中甚少使用,注意,python中没有这个函数
3、uuid3()基于名字和MD5散列值
通过计算名字和命名空间的MD5散列值得到的,保证了同一命名空间中不同名字的唯一性,和不同命名空间的唯一性,但同一命名空间的相同名字生成相同的uuid
4、uuid4()基于随机数
由伪随机数得到的,有一定的重复概率,这个概率是可以计算出来的
5、uuid5()基于名字和SAH1散列值
算法和uuid3相同,不同的是使用SHA1算法
使用经验:
1、python中没有基于DCE的,所以uuid2可以忽略
2、uuid4存在概率性重复,由于无映射性,最好不用
3、如果在全局的分布式环境下,最好使用uuid1()
4、如果名字的唯一性要求,最好使用uuid3或uuid5
简单使用
print(uuid.uuid1())
print(uuid.uuid4())
print(uuid.uuid3(uuid.NAMESPACE_DNS, "tom"))
print(uuid.uuid5(uuid.NAMESPACE_DNS, "tom"))
print(uuid.uuid5(uuid.NAMESPACE_DNS, "tom"))
#
c9abcfa2-aacf-11e9-a290-f4b7e20ea694
0e196870-d353-4d02-a8cc-69d240c90e84
f973ba0f-cf78-3bb8-ade3-4c7b492d9e55
b73c6264-f580-56d3-9a04-299b8616690e
b73c6264-f580-56d3-9a04-299b8616690e
collections是python内建的一个集合模块,提供了许多有用的集合类(类型)
命名元组,本质是一个函数,用它来创建一个自定义的tuple对象
规定tuple元素的个数,并可以用属性而不是索引来引用tuple中的元素
使用namedtuple定义了一个新的数据类型
#d定义一个新的数据类型,
'''
参数1:类型名字
参数2:列表,给创建出来的命名元组类型的数据的元素起名字
'''
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p2 = Point(y=1, x=2) # p2 = Point(1, 2)
print(p2, type(p2))
#Point(x=2, y=1)
print(isinstance(p2, Point))
#True
print(isinstance(p2, tuple))
#True
#获取命名元组中的元素
print(p2[0], p2[1]) # 2 1
print(p2.x, p2.y) # 2 1
使用list存储数据,按索引访问元素,但是插入和删除元素会根据元素的个数增多而降低效率,因为list是显性存储,数据量大插入和删除效率会降低,而且list属于非线程安全的数据类型
deque就是为了高效实现插入和删除操作,且是线程安全的数据类型,作为双向列表,适用于队列和栈
简单使用
from collections import deque
deq = deque([1,2,3,4,5])
print(deq) #deque([1, 2, 3, 4, 5])
deq.append(6)
print(deq) #deque([1, 2, 3, 4, 5, 6])
deq.appendleft(0)
print(deq) #deque([0, 1, 2, 3, 4, 5, 6])
print("------",deq.pop()) #------ 6
print(deq) #deque([0, 1, 2, 3, 4, 5])
deq.popleft()
print(deq) #deque([1, 2, 3, 4, 5])
print(deq[3]) #4
使用dict时,如果引用的key不存在,会抛出KeyError的异常(若使用get()方法会得到None)。如果希望key不存在时,能得到一个默认在的值,就使用defaultdict
d2 = defaultdict(lambda :-1)
d2["a"] = 1
d2["b"] = 2
print(d2["a"]) #1
print(d2["c"]) #-1
print(d2.get("d")) #获取不到key对应的值得到None
from collections import OrderedDict
d2 = OrderedDict([("a", 1),("c", 3),("b", 2)])
print(d2) #OrderedDict([('a', 1), ('c', 3), ('b', 2)])
print(d2["a"]) #1
print(d2.get("b")) #2
print("--------------")
# print(d2["d"]) #报错
print(d2.get("d")) #None
from collections import Counter
#变量c本质是一个字典,
a = 'hello world'
c = Counter()
c["a"] = 1
c["b"] = 2
print(c["a"])
print(c["d"])
print(c, type(c), isinstance(c, dict)) #Counter({'b': 2, 'a': 1}) True
for ch in a:
c[ch] = c[ch] + 1
print(c) #Counter({'l': 3, 'b': 2, 'o': 2, 'a': 1, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
概述:用记事本打开图片等文件,看到的是一坨乱码,因为二进制文件包含很多无法显示的内容。所以想让记事本能处理二进制数据,需要将二进制字符串转换,base64是一种比较常见的二进制编码方式
编码原理:
一个包含64个字符的列表
[‘A’, ‘B’, ……, ‘Z’,‘a’, ‘b’, ……, ‘z’, ‘0’, ‘1’, ……, ‘9’, ‘+’, ‘/’]
对二进制数据进行处理,每三个字节一组,一组就是3x8=24bit,划为4组,每组正好6bit
得到4个数字作为索引,然后查表,获得相应4个字符,就是编码后的字符串
作用:适用于小段内容编码,比如数字证书签名、cookie、网页中传输的少量二进制数据
如果编码的二进制不是3的倍数,怎么办?
简单使用
import base64
#编码
s1 = b"sunck is a good man" #字节串,二进制的数据
'''
sun对应的编码
011100 110111 010101 101110
28 55 21 46
n 对应的编码
011011 100000 000000 000000
'''
print(base64.b64encode(s1))
s2 = b'c3VuY2sgaXMgYSBnb29kIG1hbg==' #b'c3VuY2sgaXMgYSBnb29kIG1hbg=='
#解码
print(base64.b64decode(s2)) #b'sunck is a good man'
s3 = b"sunck is a good m~"
print(base64.b64encode(s3))
print(base64.urlsafe_b64encode(s3))
s4 = b'c3VuY2sgaXMgYSBnb29kIG1-'
print(base64.urlsafe_b64decode(s4))
摘要算法(又称哈希算法、散列算法)
s1 = b"tom is a good man"
m1 = hashlib.md5()
m1.update(s1)
print(m1)
#
res1 = m1.hexdigest()
print(res1, type(res1))
#b49b5dc2b05db94179474bd4b1cefad9
#如果数据量较大,可以分多次调用update,最后得到的结果是一样的
m2 = hashlib.md5()
m2.update(b"tom is ")
m2.update(b"a good man")
res2 = m2.hexdigest()
print(res2)
#b49b5dc2b05db94179474bd4b1cefad9
s3 = b"tom is a good man"
h3 = hashlib.sha1()
h3.update(s3)
res3 = h3.hexdigest()
print(res3, type(res3)) #cee73cb1dcd6e85d1f714e37f9a9ce2081fb0977
更安全
SHA256
SHA512
越安全的算法不仅越慢,而且摘要会越长
有没有两个不同的数据通过hash运算后得到相同的摘要呢?
应用
任何允许用户登录的网站都会存储用户登录的用户名和密码,那么密码一般存储的都是原密码的摘要值
如果明文存储到数据库中,如果数据库泄露,所有用户信息都会暴露
正确的保存口令方式不是存储明文内容,而是存储口令的摘要,当用户登录时,首先会计算用户输入的明文口令的摘要,和数据库中的对比,如果一致说明口令正确,否则一定错误
实现了hmac算法,是用一个key对数据进行“杂凑”后在进行的hash,使用hmac比hash算法更安全,不同的key产生不同的hash值
import hmac
s = b"tom is a good man"
key = b"secret"
h = hmac.new(key, s, digestmod="SHA1")
res1 = h.hexdigest()
print(res1)
#8b30502efa35ada5d128070ec73a1fcc1cba41f1
import itertools
import time
#1、count(start=0, step=1)
c = itertools.count()
print(c, type(c)) #count(0)
for i in c:
print(i)
time.sleep(0.5)
# 2、cycle(iterable)
# 把传入的一个序列无限重复下去
cyc = itertools.cycle("tom") #
print(cyc, type(cyc))
for i in cyc:
print(i)
time.sleep(0.5)
# 3、repeat(object[, times])
# 把一个元素无限重复下去,如果提供了第二个参数,就可以指定重复的次数
r = itertools.repeat("tom")
for i in r:
print(i)
time.sleep(0.5)
import itertools
# 1、chain([iterable[, iterable, ……]])
# 把一组迭代对象串联起来,形成一个更大的迭代器
ch = itertools.chain("ABC", "abc")
#
for i in ch:
print(i)
#2、groupby(iterable)
# 把迭代器中相邻的重复元素挑出来放在一起
g = itertools.groupby("AAAABBBAAccdeffgHHH")
print(g,type(g))
#
for key, value in g:
print(key, list(value))
'''
A ['A', 'A', 'A', 'A']
B ['B', 'B', 'B']
A ['A', 'A']
c ['c', 'c']
d ['d']
e ['e']
f ['f', 'f']
g ['g']
H ['H', 'H', 'H']
'''
#排列
# #从n个不同的元素中取出m(m<=n)个元素按照一定的顺序排成一列,叫做从n个元素中获取m个元素的一个排列,当m==n时,这个排列称为全排列
#从n个中选m个 n!/(n-m)!
li1 = [1,2,3,4]
p1 = list(itertools.permutations(li1, 2))
#
print(p1)
print(len(p1))
#从n不同元素中,任意m(m<=n)个元素为一组,叫做从n个不同元素中取出m个元素的组合
#从n个不同元素中获取m个 n!/m!x(n-m)!
li2 = [1,2,3,4]
p2 = list(itertools.combinations(li2, 2))
print(p2)
print(len(p2))
##排列组合(笛卡尔积)
#从n个元素中获取m个元素 n^m
li3 = "qwertyu"
p3 = list(itertools.product(li3, repeat=2))
print(p3)
print(len(p3))
#暴力破解
import time
s4 = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM"
passwds = ("".join(x) for x in itertools.product(s4, repeat=16))
for i in passwds:
print(i)
time.sleep(1)
from PIL import Image
#打开图片
im = Image.open("fengjing.jpg")
#查看图片信息
print(im.format, im.size, im.mode)
#JPEG (1920, 1200) RGB
#修改图片大小
im.thumbnail((192, 120))
#生成新图片
im.save("fengjing2.jpg", "JPEG")
# 放缩图片: 原图像缩放为128x128
im_resized = im.resize((128, 128))
#显示图片
im_resized.show()
# 旋转图片: 指定逆时针旋转的角度
img_rotate = im.rotate(45) # 旋转之后的图片的大小并不会发生变化,旋转的留白区域会用黑色填充
img_rotate.show()
# 翻转图片:图像的翻转用 transpose()函数,直接在入参中指定变换方式即可,不仅支持上下、左右翻转;也支持逆时针90、180、270等角度的旋转,效果与rotate()相同。示例如下:
out_lr = im.transpose(Image.FLIP_LEFT_RIGHT) # 左右翻转
out_lr.show()
out_tb = im.transpose(Image.FLIP_TOP_BOTTOM) # 上下翻转
# out_tb.show()
# out = img.transpose(Image.ROTATE_90) # 逆时针旋转九十度
# out = img.transpose(Image.ROTATE_180)
# out = img.transpose(Image.ROTATE_270)
# out.show()
# 编写函数,实现给函数一个大于等于1的整数数字,求1+2+3+……+n的和
def my_sum2(num):
if num == 1:
return 1
else:
return my_sum2(num-1) + num
#原理
'''
my_sum2(5)
my_sum2(4) + 5
my_sum2(3) + 4 + 5
my_sum2(2) + 3 + 4 +5
my_sum2(1) + 2 + 3 + 4 + 5
1 + 2 + 3 + 4 + 5
'''
递归和迭代的区别:
递归:重复调用函数自身实现循环称为递归;
递归实际上不断地深层调用函数,直到函数有返回才会逐层的返回,递归是用栈机制实现的,每深入一层,都要占去一块栈数据区域,因此,递归涉及到运行时的堆栈开销(参数必须压入堆栈保存,直到该层函数调用返回为止),所以有可能导致堆栈溢出的错误;但是递归编程所体现的思想正是人们追求简洁、将问题交给计算机,以及将大问题分解为相同小问题从而解决大问题的动机。
例如:if else 调用自己,并在合适时机退出
迭代:利用变量的原值推出新值称为迭代,或着说迭代是函数内某段代码实现循环;
迭代大部分时候需要人为的对问题进行剖析,分析问题的规律所在,将问题转变为一次次的迭代来逼近答案。迭代不像递归那样对堆栈有一定的要求,另外一旦问题剖析完毕,就可以很容易的通过循环加以实现。迭代的效率高,但却不太容易理解,当遇到数据结构的设计时,比如图表、二叉树、网格等问题时,使用就比较困难,而是用递归就能省掉人工思考解法的过程,只需要不断的将问题分解直到返回就可以了。
例如:for,while循环
两者关系:所有的迭代可以转换为递归,但递归不一定
定义 | 优点 | 缺点 | |
---|---|---|---|
递归 | 重复调用函数自身实现循环 | a.用有限的循环语句实现无限集合;b.代码易读; c.大问题转化成小问题,减少了代码量。 | a.递归不断调用函数,浪费空间 b.容易造成堆栈溢出 |
迭代 | 利用变量的原值推出新值; 函数内某段代码实现循环。 | a.效率高,运行时间只随循环的增加而增加;b.无额外开销。 | a.代码难理解;b.代码不如递归代码简洁; c.编写复杂问题时,代码逻辑不易想出 |
两者关系 | a.递归中一定有迭代,但是迭代中不一定有递归;大部分可以相互转换。 | b.相对来说,能用迭代不用递归(因为递归不断调用函数,浪费空间,容易造成堆栈溢出) |
#栈
#特点:先进后出
myStack = []
#压栈(往栈结构存储数据)
myStack.append(1)
print(myStack)
myStack.append(2)
print(myStack)
myStack.append(3)
print(myStack)
#出栈
myStack.pop()
print(myStack)
myStack.pop()
print(myStack)
myStack.pop()
print(myStack)
#队列
#特点:先进先出
from collections import deque
q = deque([1,2,3,4])
#进队
q.append(5)
print(q)
q.append(6)
print(q)
#出队
q.popleft()
print(q)
q.popleft()
print(q)
q.popleft()
print(q)
q.popleft()
print(q)
官方文档
详细解读
详细解读
详细解读
pygame.init() #初始函数,使用pygame的第一步;
pygame.display.set_mod((600,500),0,32) #生成主屏幕screen;第一个参数是屏幕大小,第二个0表示不使用特性,可用FULLSCREEN,RESIZEBLE,NOFRAME,DOUBLEBUF(双缓冲,使用时需用pygame.display.flip()来刷新屏幕)等替换,32表示色深;
pygame.display.set_caption("string") #命名
pygame.display.update() #刷新
pygame.display.list_modes() #查看本地显示器支持的分辨率;
screen.fill(0,0,0) #填充
pygame.draw.rect(surface,color,Rect,width=0) 画一个矩形,Rect为两个坐标元组的元组;
r.left 左边x坐标的整数值
r.right 右边x坐标的整数值
r.top 顶部y坐标的整数值
r.bottom 底部y坐标的整数值
r.centerx 中央x坐标整数值
r.centery 中央y坐标整数值
r.width 宽度
r.height 高度
r.size 即元组(width,height)
r.topleft (left,top)
r.topright (right,top)
r.bottomleft (left,bottom)
r.bottomright (right,bottom)
r.midleft (left,centery)
r.midright (right,centery)
r.midtop (centerx,top)
r.midbottom (centerx,bottom)
pygame.draw.polygon(surface,color,pointlist,width=0) 多边形
pygame.draw.circle(surface,color,pos,radius,width=0) 圆
pygame.draw.ellipse(surface,color,Rect,width=0) 椭圆
pygame.draw.arc(surface,color,Rect,start_angle,stop_angle,width=1) 圆弧
pygame.draw.line(surface,color,start_pos,end_pos,width=1) 直线;
pygame.draw.lines(surface,color,closed,pointlist,width=1) closed为一bool值,表示是否封闭;
pygame.draw.aaline(surface,color,start_pos,end_pos,width=1) 一根平滑的线;
pygame.draw.aalines(surface,color,closed,pointlist,width=1) 一系列平滑的线;
1.pygame.font.Font("字体","字号",*)
2.my_font.render(text,True,(255,255,255)) 使用已有的文本创建一个位图image,返回值为一个image;对于位图可用get_height(),get_width()的方法获得高与宽;True表示是否抗锯齿,第三个为字体颜色,还可以有第四个为背景色,没有时就为默认的透明;
3.Font() 使用的是字体文件,要使用系统中的字体需用SysFont(),但一些中文扩展的字体不是很好用。
4.screen.blit(image,(100,100)) 将位图绘制到屏幕上,screen为建立的主屏;
5.pygame.font.get_fonts() 查看当前系统所有可使用的字体
pygame支持的图片格式有:JPEG,PNG,GIF,BMP,PCX,TGA,TIF,LBM,PBM,XPM
pygame.image.load("图片路径").conver() 将图片处理为surface对象,如果使用conver_alpha()则保留了Alpha通道信息(可透明),使用时用blit()函数来添加到显示屏
pygame.Surface((250,250),flags,depth) 创建一个surface对象,如果不指定尺寸则会创建和屏幕一样大小;flags为可选,有SRCALPHA(保留Alpha通道)、HWSURFACE(优化)两个选择,depth为色深;
screen.subsurface((0,0),(80,80)) 子表面对象;
screen.set_at(pos,color) 设置一个像素的色彩;
screen.get_at(pos) 获取某一像素的色彩,不过此操作的反应比较慢;
pygame.transform.scale(surface,(width//2,height//2) 缩放图片
pygame.transform.smoothscale(surface,(width,height) 缩放图片,比scale慢,但效果更好;
pygame.sprite.Group() 精灵组,一个简单的实体容器;
pygame.sprite.add(sprite) 添加精灵对象;
pygame.sprite.update(ticks)
pygame.sprite.draw(screen)
pygame.sprite.collide_rect(arrow,dragon) 冲突
screen.set_clip(0,400,200,600) 设定裁剪区域;
screen.get_clip() 获得裁剪区域
1 pygame.event.get() 获取事件的返回值,使用event.type == 进行区分
2 pygame.event.wait() 等待发生一个事件才会继续下去;
3 pygame.event.poll() 会根据现在的情形返回一个真实的事件
4 pygame.event.set_blocked(事件名) 过滤
5 pygame.event.set_allowed() 允许事件
自定义事件
1 my_event = pygame.event.Event(KEYDOWN,key=K_SPACE,mod=0,unicode=u' ')
2 pygame.event.post(my_event)
pygame所有事件type
QUIT 退出;
ACTIVEEVENT pygame被激活或隐藏;
KEYDOWN 区分不同键 event.key == pygame.K_a,pygame使用keys=pygame.key.get_pressed()来轮询键盘接口,返回的是所有按下键值的元组;用keys[K_b]方式来核对键值;K_b也可以是键值Unicode码;如果mod & KMOD_CTRL为真的话表示同时按下Ctrl键;key.get_mods()组合键,key.set_repeat()重复事件;key.name()接受键值返回键名;
KEYUP 按键放开
MOUSEMOTION 含event.pos,event.rel,event.buttons属性,用mouse_x,mouse_y = event.pos进行确认,pygame.mouse.get_pos()返回鼠标的当前位置,pygame.mouse.get_rel()获取鼠标相对移动,pygame.mouse.get_pressed()返回按钮状态数组(鼠标三个键的状态)
mouse.set_visible(False) 使鼠标不可见;
event.set_grab(True) 使鼠标不会跑出窗口
mouse.set_pos() 设置鼠标位置
mouse.get_focused() 如果鼠标在pygame窗口内有效,返回True
mouse.set_cursor() 设置鼠标默认光标式样;
mouse.get_cursor() 获取鼠标默认光标式样;
MOUSEBUTTONUP 鼠标放开
MOUSEBUTTONDOWN 鼠标按下
JOYAXISMOTION x手柄移动
JOYBALLMOTION 所有手机移动
JOYHATMOTION hat手柄移动
JOYBUTTONUP 手柄按键放开
JOYBUTTONDOWN 手柄按键按下
VIDEORESIZE 窗口缩放;
VIDEOEXPOSE 窗口部分公开;
USEREVENT 触发了一个用户事件;
try:
screen = pygame.display.set_mode(SCREEN_SIZE)
except pygame.error,e:
print("Can't create the display :-(")
print(e)
exit()
1 clock = pygame.time.Clock() 初始化一个clock对象
2 clock.tick() 返回一个上次调用的时间,以毫秒为单位
3 clock.tick(30) 控制游戏绘制的最大帧率为30
(一)sound对象
pygame.mixer.Sound(“文件”) 读取声音对象sound,格式只有wav和ogg两种;
对象方法:
1 fadeout() 淡出时间,可用参数为毫秒;
2 get_lengh() 获得声音文件长度,以秒为单位;
3 get_num_channels() 声音要播放的次数;
4 play(loop,maxtime) 对读取的声音对象可执行播放操作,loop为-1表示无限循环,1表示重复两次,maxtime表示多少毫秒后结束;返回一个Channel对象,失败则返回None;
5 set_volum() 设置音量;
6 stop() 停止播放;
7 pygame.mixer.music 背景音乐处理方法
8 pygame.mixer.music.load() 加载文件可为mp3和ogg格式;
9 pygame.mixer.music.play() 播放
10 pygame.mixer.music.stop() 停止,还有pause()和unpause()方法
(二)Channels对象
pygame.mixer.get_num_channels() 获取当前系统可同时播放的声道数;pygame中默认为8;
对象方法:
1 fadeout() 设置淡出时间
2 get_busy() 如果正在播放,返回True;
3 set_endevent() 设置播放完毕时要做的event;
4 get_endevent() 获取播放完毕时要做的event,如果没有则返回None;
5 get_queue() 获得队列中的声音,如果没有则返回None;
6 set_volume() 设置音量;
7 get_volume() 获得音量;
8 pause() 暂停播放;
9 unpause() 继续播放;
10 play() 播放;
11 stop() 停止播放;
12 queue() 将一个Sound对象加入队列,在当前声音播放完毕后播放;
13 set_num_channels() 自定义声道数;
(三)music对象
pygame.mixer.pre_init(frequency,size,stereo,buffer) 声音系统初始化,第一个为采样率,第二个为量化精度,第三为立体声效果,第四为缓冲;
对象方法:
1 fadeout() 设置淡出时间
2 set_endevent() 设置播放完毕后事件
3 get_endevent() 获取播放完毕后进行的事件;
4 set_volume() 设置音量;
5 get_volume() 获取音量;
6 load() 加载音乐文件;
7 rewind() 从头开始播放;
8 get_pos() 获得当前播放的位置,以毫秒为单位;
from pygame.locals import *
import pygame
import sys
import time
import random
# 初始化窗口
class Window(object):
def __init__(self):
# 初始化pygame
pygame.init()
# 刷新速度
self.fpsClock = pygame.time.Clock()
# 创建pygame显示层
self.playSurface = pygame.display.set_mode((640, 480))
# 设置标题
pygame.display.set_caption('贪吃蛇')
# 定义结束窗口
def gameOver(self, color):
# 设置字体
gameOverFont = pygame.font.SysFont('Arial', 72)
# 设置字体属性
gameOverSurf = gameOverFont.render('Game Over', True, color)
#
gameOverRect = gameOverSurf.get_rect()
# 设置字体位置
gameOverRect.midtop = (320, 240)
# 在窗口显示
self.playSurface.blit(gameOverSurf, gameOverRect)
# 刷新窗口
pygame.display.flip()
time.sleep(5)
pygame.quit()
sys.exit()
# 定义snake类
class Snake(object):
def __init__(self):
# 初始化snake出现位置
self.snakeHead = [100, 100]
self.snakeBody = [[100, 100], [80, 100], [60, 100]]
# 移动的方向
self.direction = 'right'
self.changeDirection = self.direction
# 定义键盘事件
def key_Event(self):
# 检测键盘事件
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
# 判断键盘事件
if event.key == K_RIGHT or event.key == ord('d'):
self.changeDirection = 'right'
if event.key == K_LEFT or event.key == ord('a'):
self.changeDirection = 'left'
if event.key == K_UP or event.key == ord('w'):
self.changeDirection = 'up'
if event.key == K_DOWN or event.key == ord('s'):
self.changeDirection = 'down'
if event.key == K_ESCAPE:
pygame.event.post(pygame.event.Event(QUIT))
# 移动
def move(self):
# 判断是否输入了当前移动方向的反方向
if self.changeDirection == 'right' and not self.direction == 'left':
self.direction = self.changeDirection
elif self.changeDirection == 'left' and not self.direction == 'right':
self.direction = self.changeDirection
elif self.changeDirection == 'up' and not self.direction == 'down':
self.direction = self.changeDirection
elif self.changeDirection == 'down' and not self.direction == 'up':
self.direction = self.changeDirection
# 根据方向移动蛇头的坐标
if self.direction == 'right':
self.snakeHead[0] += 20
elif self.direction == 'left':
self.snakeHead[0] -= 20
elif self.direction == 'up':
self.snakeHead[1] -= 20
elif self.direction == 'down':
self.snakeHead[1] += 20
def eat(self, food):
self.snakeBody.insert(0, list(self.snakeHead))
# 判断是否吃掉了food
if self.snakeHead[0] == food.raspberryPosition[0] and self.snakeHead[1] == food.raspberryPosition[1]:
x = random.randrange(1, 32)
y = random.randrange(1, 24)
food.raspberryPosition = [int(x * 20), int(y * 20)]
else:
self.snakeBody.pop()
# 定义Food类
class Food(object):
def __init__(self):
# 出现位置
self.raspberryPosition = [300, 300]
#
# 拓展
#
# 通过判断snakes的长度来调整游戏速度和food数量
'''
def add_food(self,obj1,obj2):
num =len(obj2.snakeBody)
if num>0 and num<10:
obj1.fpsClock.tick(5)
if num>=10 and num <20:
obj1.fpsClock.tick(10)
if num>=20:
obj1.fpsClock.tick(13)
'''
def main():
# 定义颜色
redColour = pygame.Color(255, 0, 0)
blackColour = pygame.Color(0, 0, 0)
whiteColour = pygame.Color(255, 255, 255)
greyColour = pygame.Color(150, 150, 150)
# 定义窗口,snake,food
user_Interface = Window()
snake = Snake()
food = Food()
# img=pygame.image.load(r'C:\Users\LAB\Desktop\1.jpg')
while True:
# 设置窗口背景色
user_Interface.playSurface.fill(blackColour)
# 设置snake和food的位置及颜色
for position in snake.snakeBody:
pygame.draw.rect(
user_Interface.playSurface, whiteColour, Rect(
position[0], position[1], 20, 20))
pygame.draw.rect(user_Interface.playSurface, redColour, Rect(
food.raspberryPosition[0], food.raspberryPosition[1], 20, 20))
# 键盘事件
snake.key_Event()
# 移动snake
snake.move()
# 吃食物
snake.eat(food)
# 判断是否死亡
if snake.snakeHead[0] > 620 or snake.snakeHead[0] < 0 or snake.snakeHead[1] > 460 or snake.snakeHead[1] < 0:
user_Interface.gameOver(greyColour)
else:
for snakeBody in snake.snakeBody[1:]:
if snake.snakeHead[0] == snakeBody[0] and snake.snakeHead[1] == snakeBody[1]:
user_Interface.gameOver(greyColour)
# 刷新界面
pygame.display.flip()
# food.add_food(user_Interface, snake)
user_Interface.fpsClock.tick(5)
if __name__ == '__main__':
main()