python包管理器pip

安装

1
2
python -m ensurepip
python -m pip install --upgrade pip

Python 基础语法

注释

1
2
3
4
5
6
7
8
9
# 单行注释
print("helldo world") # 行尾注释

"""
这是一个多行注释
...
..
结束注释
"""

运算符操作

1
2
3
4
5
6
20 // 6  #整除
20 / 6 #除法
10 % 3 #取余数
2 ** 5 #乘方
1<<30 #位运算
1 if x=2 else 2 # 三目运算符

字符串

  1. 双引号 中间可以加转义字符
  2. 单引号 纯字符输出
  3. 三引号 多行字符串
1
2
3
4
5
6
"Hello" + 'world'   # +号不能连接数字
"""
Hello
World
"""
print("Hello"*3) #输出3次Hello

字符串函数

1
len("ddd") # 字符串长度
判断类型方法
1
2
3
4
5
6
string.isspace() # 是否是单个空格" "
string.isalnum() # 是否是数字或字母
string.isalpha() # 是否是字母
string.isdigit() # 是否是数字
string.islower() # 是否是小写
string.isupper() # 是否是大写
查找和替换
1
2
3
4
string.startswith(str) # 是否以str开头
string.endswith(str) # 是否以str结尾
string.find(str, start=0, end=len(string)) # 查找str是否包含其中,start和end给出范围,如果有返回开始的位置,没有就是-1
string.rfind(str,s,e) # 从右边找的find
转换类方法
1
2
3
string.lower() # 转换成小写
string.upper() # 转换成大写
string.swapcase() # 翻转大小写
文本对齐
1
2
3
4
5
6
string.ljust(width) # 左对齐
string.rjust(width) # 右对齐
string.center(width) # 居中
string.lstrip() # 去除左边空格
string.rstrip() # 去除右边空格
string.strip() # 去除左右空格
拆分和连接
1
2
3
4
5
string.partition(str) # 把字符串分成str左边,str和str右边3个字符串
string.rpartition(str) # 同上,从右边查找
string.spilt(str="",num) # 以str为分隔符,分割num+1个字符串
string.spiltlines() # 按照\r \n 分割
string.join(seq) # 把seq中的字符串合成1个

输入输出

1
2
3
4
5
6
7
8
9
print("Hello world")
a = input("please input a")
print(a+2)
print(int(input())+2) # 输出输入的数+2

a = 34
b = 12
print("the integer: %06d and the float: %.4lf" % (a, b)) # 格式化输入输出
# the integer: 000034 and the float: 12.0000

类型转换

1
2
print(int("2333"))   # 字符串转int
float(2)+float("233") #int/string 转float

变量

1
2
f = 1
del f #删除已经定义的变量

全局变量

python中不允许修改全局变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
num = 10


def func1():
num = 12
print(num)


def func2():
print(num)


func1()
func2()
# 12
# 10

需要使用global声明全局变量,才不会创建全局变量而是使用局部变量。定义全局变量要在函数的上方,建议命名的时候前面加上g_或者gl_

1
2
3
4
def func1():
global num
num = 12
print(num)

流程控制语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if a > 0 and b > 0:
print(a)
if a < 0 or c < 9: print(a)
elif not a == 0:
print("==0")
else: print(-a)

i = 1
while i <= 5:
print(i)
if i == 2: break
else: continue

a = 2

for i in b:
print(i)

for i in c:
if i == d:
break
else:
print("not found")

Lists

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
a = [0,[1,2],2,3,] + [2,3,4]*2  # [0,[1,2],2,3,2,3,4,2,3,4]
a += [1,2,3] # += 操作对于列表而言本质上调用了extend方法
a.sort(reverse=False) # 升序排序,reverse参数用于降序排序
print(a[3]) # 3
print(a)
if 3 in a: # 查找a中的元素
print(True)
elif 4 not in a:
print("4notina")
a.append(5) #再a的末尾+5
print(len(a)) #a的长度
a.insert(1,2) #在1的位置插入2
print(a.index(0)) # 查找元素0的第一个index
t = max(a) - min(a)
t = list.count(1) #数1的个数
a.remove(1) #删除第一个1
a.reverse() #反转列表
b = list(range(10)) #生成一个0到9的列表
b = list(range(3,8)) #3到7
b = list(range(5,20,2)) #5-19间隔2
for i in range(1,10):
print(i)

for index, i in enumerate(list):
list[index] = i*2

切片

[开始索引:结束索引:步长] ,切片结果左闭右开

1
2
3
4
5
6
7
arr = [1,2,3,4,5,6]
arr[1:-3] # 在1砍一刀,在倒数第三个2位置砍一刀
# [2,3]
arr[1:-3:2] # 跳跃切片,步长2
# [2]
arr[::-2] # 倒序步长
# [5, 3, 1]

OI控制台输入输出

1
2
3
if __name__ == '__main__':
# main函数
n = int(sys.stdin.readline())

函数

函数传参是类似java的引用传参模式。只有使用方法可以修改外部数据,直接修改引用无效。

1
2
3
4
def mysum(a, b):
return a + b, a - b # 返回一个元组(a+b,a-b)

s, t = sum(1, 3) # 多个变量收取返回值

多值参数

一个*代表元组,**代表字典

1
2
3
4
5
6
7
8
9
10
11
12
def demo(num, *args, **kwargs):
print(num)
print(args)
print(kwargs)


demo(1, 2,3,4,5,age=3,pp=3)
'''
1
(2, 3, 4, 5)
{'age': 3, 'pp': 3}
'''
拆包

如果像把变量放到多值函数中调用的话,需要使用拆包

1
2
3
4
nums = (1,5,1,3,4)
dic = {"age":3, "pp":4}

demo(1, *nums, **dic)

内部函数

内部函数可以访问外部函数的局部可变变量,比如数组。但是不能修改不可变变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def func1():

n = 10
m = 11
list = [1, 2, 3]

def in_func():

for index,i in enumerate(list):
list[index] = i + n # 可以访问n,但是不能修改

nonlocal m # 要修改一定要声明nonlocal
m = 12


in_func()
print(n, m)
print(list)

return in_func # 函数也可作为返回值
"""
10 12
[11, 12, 13]
"""

闭包

  1. 必须要有内部函数。
  2. 外部函数有返回值
  3. 返回值是内部函数

比如上面这个例子就是一个闭包。它可以用来封装函数,可以使得代码简介。下面的函数可以做成一个生产计数器的函数。

1
2
3
4
5
6
7
8
9
10
11
12
def generate_counter():
counter = [0]

def add_one():
counter[0] += 1
print("No. %d" % counter[0])

return add_one

counter = generate_counter()
counter()
counter()

装饰器

装饰器是闭包使用函数作为参数,它可以不改函数名的条件下扩展函数的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def decorate(func):
print("out")

def wrapper(*args,**kwargs):
func(*args,**kwargs)
print("color")
print("new things")

return wrapper

@decorate2 # 多层装饰器,顺序从低向上
@decorate # 使用装饰器 相当于 house = decorate(house)
def house():
print("old house")

house()
带参数装饰器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def outer(a):
def decorate(func):
print("out")

def wrapper(*args,**kwargs):
func(*args,**kwargs)
print("color")
print("new things %d" % a)

return wrapper
return decorate

@outer(10) # 要再加一层
def house():
print("old house")

house()
付款案例

要实现先登录才能付款的功能

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
def login():
name = input("username:")
passwd = input("passwd:")
print("login sucessful")
return True

islogin = False

def login_required(func):
def wrapper(*args,**kwargs):
global islogin
if not islogin:
islogin = login()

if islogin:
func(*args,**kwargs)
return wrapper


@login_required
def pay(money):
print("正在付款,金额是:{}元".format(money))
print("付款")
time.sleep(2)
print('付款成功')


pay(100)

匿名函数

lambda表达式

1
2
3
4
5
s = lambda a, b: a + b
b = s(1,2)
print(b)

func(lambda a:a+2)

可以再max函数里指定比较对象

1
2
3
list = [{'a':10, 'b':20}, {'a':13, 'b':12}]
m = max(list,key=lambda x:x['b'])
print(m)

可以对列表元素操作

1
2
3
list2 = [1, 2, 3, 4, 5]
result = map(lambda x:x+1, list2)
print(list(result))

可以进行加和的操作

1
2
3
4
from functools import reduce
list2 = [1, 2, 3, 4, 5]
result = reduce(lambda x,y: x+y, list2)
print(result)

过滤操作

1
2
result = filter(lambda x:x > 3,list2)
print(list(result))

模块

1
2
3
4
5
6
7
8
9
10
import mod1
import numpy as np
from mod1 import func1

def main():
pass

if __name__ == '__main__':
main()
# 在导入模块的时候,main下面的不会被执行

可以通过导入包,导入包中所有的模块。但是包里面一定要包含__init__.py的文件

image-20200406123434745

可以这样创建python的包

命令行参数

sys中的argv是传入的参数

1
2
3
import sys

print(sys.argv)

面向对象

创建对象

在类中的方法,第一个参数必须是self

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Cat:

def __init__(self, str="hhh"):
self.name = str
self.__age = 18 # 前面加两个下划线是私有属性

def __secret(self): # 私有方法
print("siyou")

def showage(self):
self.__secret()
print(self.__age)

def __del__(self):
print("over")

def __str__(self):
return self.name

def eat(self):
print("eat %s" % self.name)

使用对象

1
2
ca = Cat()
ca.eat()

伪私有方法

_类名__变量 是python底层访问私有方法的机制

1
print(cat._Cat__age)  

继承

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
class Animal:

count = 0 # 类变量

def __init__(self):
Animal.count += 1

@classmethod # 定义类方法
def classname(cls):
print("class method")

@staticmethod # 定义静态方法
def sum(a,b):
return a + b

def eat(self):
print("aeat")

def say(self):
pass

class Dog(Animal): # 父类写括号里,多继承在后面加逗号即可

def shout(self):
print("www")

def say(self): # 方法的重写
print("wang")
super().eat() # 调用父类方法

print(Dog.__mro__) # 打印Dog类的方法调用顺序

python中,类是一个特殊的对象

单例

只会产生一个实例的类。object类中的静态方法__new__方法可以分配空间,返回对象的引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MusicPlayer(object):

instance = None

def __new__(cls, *args, **kwargs):
print("创建对象,分配空间")
if cls.instance is None: # 如果没有地址才分配
cls.instance = super().__new__(cls)
return cls.instance # 返回分配的地址

def __init__(self):
print("init")


player = MusicPlayer()
player2 = MusicPlayer()
print(player)
print(player2)

异常

捕获异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import traceback

try:
num = int(input())
c = 1/num
except ValueError:
print("Please Input an Integer")
traceback.print_exec() # 打印回溯
except Exception as result:
print("Unknown Error: %s" % result)
else:
# 没有异常执行
finally:
# 最终都会执行

抛出异常

1
2
3
def funcerror():
ex = Exception("Message")
raise ex

文件

文件读取

1
2
3
4
5
6
file = open("../d.txt","r",encoding='UTF-8')

text = file.read() # 可以读取文件的全部内容
print(text)

file.close()

文件写入

1
2
3
4
5
6
7
8
file = open("../d.txt", "w")  # a 是追加, w是重写  "b" 是二进制模式 


#text = file.read()
#print(text)
file.write("str")

file.close()

OS模块

1
2
3
4
5
6
7
import os

print(os.listdir(".")) # 列出所有文件
print(os.path.isdir("./Include")) # 判断是否是文件夹

os.getcwd() #获得当前目录

With

with可以自动管理内存,十分方便

1
2
with open("plane_main.py", "r") as f:
print(f.read())

生产器

集合推导式

1
2
3
list1 = [1, 2, 3, 4, 1, 3, 4]
set1 = {x+1 for x in list1 if x > 2}
print(set1)

字典推导式

交换字典的键值对

1
2
3
dic1 = {'a':1, 'b':2}
newdic = {value: key for key, value in dic1.items()}
print(newdic)

我们可以通过推导式来得到生成器

1
2
3
4
g = (x*3 for x in range(20))  # 小括号是生产器
print(list(g)) # 可以用list展开
print(g.__next__(), g.__next__()) # 可以用next方法展开
print(next(g))

通过函数定义生成器

1
2
3
4
5
6
7
8
def func():
n = 0
while True:
n += 1
tp = yield n # 有yield就是生产器
print(tp)
g = func()
g.send("HH") # 可以通过send给tp赋值

迭代器

1
2
3
list1 = [1, 2, 3, 4, 1, 3, 4]
iter1 = iter(list1) # 把列表弄成迭代器
print(iter1.__next__())

多线程

创建进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from multiprocessing import Process
from time import sleep


def task1():
while True:
print("task1")
sleep(1)


def task2():
while True:
print("task2")
sleep(1)


if __name__ == '__main__':
p1 = Process(target=task1, name="t1")
p2 = Process(target=task2, name="t2")

p1.start()
p2.start()

继承Process类来创建进程

1
2
3
4
5
6
7
8
9
10
11
12
13
class MyProcess(Process):

def __init__(self, name):
super(MyProcess, self).__init__()
self.name = name

def run(self) -> None:
while True:
print(self.name)
sleep(1)

mp1 = MyProcess("p1")
mp1.start()

进程池

线程池可以设置任务的最大上限。进程池分为非阻塞式和阻塞式进程池。下面的是非阻塞式。

非阻塞式进程池先把所有任务都扔进队列里。立刻返回,没有等待其他进程结束才返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def task(taskname):
print('start', taskname, os.getpid())
start = time()
sleep(random() * 2)
end = time()
print("done, ", end - start)
return str(taskname) + " over" # 返回给回调函数


def callback_func(n):
print("back", n)

def main():
pool = Pool(5) # 5是任务的最大数量

tasks = ["sing", "play", "work", "kk", "d", "q"]

for i in tasks:
pool.apply_async(task, args=(i,), callback=callback_func)

pool.close() # 添加任务结束
pool.join() # 等待任务结束

print("over")

阻塞式只有执行完一个任务才进行下一个任务,它不需要回调函数,只能一个一个执行

1
2
for i in tasks:
pool.apply(task, args=(i,))

进程间通信

队列

多线程的队列可以设置大小,如果满了的话就会阻塞,直到可以队列不满

1
2
3
4
5
6
7
8
9
10
from multiprocessing import Queue
q = Queue(3) # 设置大小
q.put("A") # 放入值
q.put("B")
q.put("C")
print(q.get())
if q.full(): # 判断队列是否已经满了
print("full!!")
q.put("D", timeout=3)
print(q.qsize())

下面是一个模拟下载的案例

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
def download(q):
images = ["hh.png", 'tt.png', 'gg.png']
for image in images:
print("downloading:, ", image)
sleep(0.5)
q.put(image)


def getfile(q):
while True:
try:
file = q.get(timeout=2)
print("saved! ", file)
except:
print("yes")
break;

q = Queue(3)
p1 = Process(target=download, args=(q,))
p2 = Process(target=getfile, args=(q,))

p1.start()
p2.start()

print("over")

创建线程

1
2
3
4
5
6
7
8
9
10
import threading
from time import sleep

def download(a):
print(a)


if __name__ == '__main__':
t = threading.Thread(target=download, name='aa', args=(1,))
t.start()

GIL 全局解释器锁:python只要用线程默认加锁,而只要在大数据的时候才没有锁。

线程:适合耗时才做,比如爬虫,文件读写

进程:适合密集运算

线程同步
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

lock = threading.Lock()
list1 = [0]*10

def task1():
lock.acquire() # 阻塞
for i in range(len(list1)):
list1[i] = 1

lock.release()

def task2():
lock.acquire() # 阻塞
for i in range(len(list1)):
print(list1[i])
sleep(0.5)
lock.release()

if __name__ == '__main__':
t1 = threading.Thread(target=task1)
t2 = threading.Thread(target=task2)

t2.start()
t1.start()
死锁

如果A,和B两个锁同时使用,可能会出现死锁。可以重构代码,或者加参数timeout来解决

线程之间的通信

下面是生产者和消费者的例子

Pycharm使用

运行程序

第一次运行程序

image-20200404162827781

如果以后运行,只要按右上角的绿色三角箭头或者Shift+F10快捷键运行就可以了

调整字体大小

File中打开Settings,或者Ctrl+Alt+S打开设置界面

image-20200404163135186

可以再Editor中的Font中改字体和大小。宋体在这里是SimSon,不勾选Show only monospaced fonts 就可以找到了。

添加函数的注释

把单击一下函数名,然后点左边的灯泡,选插入注释

image-20200404174134342

Ctrl+Q 可以显示详细信息

安装扩展包

Ctrl+Alt+S 打开设置,然后打开Project Interpreter中的pip可以安装包

image-20200406124539768

Python游戏开发项目

需要的包是pygame,来实现一个飞机大战的项目

游戏初始化

基本框架

1
2
3
4
5
6
7
8
9
10
11
import pygame


pygame.init() # 初始化
print("game")

screen = pygame.display.set_mode((480,720))

num = input()
pygame.quit() # 结束

绘制图像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import pygame

pygame.init()
screen = pygame.display.set_mode((480,700))

# 加载图片
bg = pygame.image.load("./images/background.png")
# 绘制图像 图片,绘制起点
screen.blit(bg,(0,0))
# 绘制英雄的飞机
hero = pygame.image.load("./images/me1.png")
screen.blit(hero, (200,500))
hero_rect = pygame.Rect(150, 300, 102, 126)
# 更新屏幕
pygame.display.update()

num = input()
pygame.quit()

更新英雄位置

1
2
3
4
5
6
7
8
9
10
11
12
clock = pygame.time.Clock()  # 定义游戏时钟

while True:
clock.tick(60) # 设置游戏的帧数
hero_rect.y -= 1
if hero_rect.y + hero_rect.height <= 0:
hero_rect.y = 700

screen.blit(bg, (0, 0))
screen.blit(hero, hero_rect)

pygame.display.update() # 重新绘图

运行后可以看到飞机动起来了

image-20200406164713051

捕获事件

1
2
3
4
# 事件监听
event_list = pygame.event.get()
if len(event_list) > 0:
print(event_list)

可以看到下面捕获到的事件

image-20200406164953082
退出游戏
1
2
3
4
5
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("Exit Game...")
pygame.quit()
exit()

精灵和精灵组

可以把游戏中需要更新的对象包装成一个精灵,然后放在精灵组里面。这样就可以很方便进行更新操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pygame


class GameSprite(pygame.sprite.Sprite):

def __init__(self, image_name, speed=1):
# 调用父类初始化方法
super().__init__()
# 定义属性
self.image = pygame.image.load(image_name)
self.rect = self.image.get_rect()
self.speed = speed

def update(self):

# 在垂直方向上移动
self.rect.y += self.speed

使用

1
2
3
4
5
6
7
8
# 创建精灵和精灵组
enemy = GameSprite("./images/enemy1.png")
enemy_group = pygame.sprite.Group(enemy)

# 让组中所有精灵更新位置
enemy_group.update()
# 绘制图像
enemy_group.draw(screen)

背景图片滚动效果

实际上是两个图片来实现滚动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Background(GameSprite):
""" 游戏背景精灵"""

def __init__(self, is_alt=False):
super().__init__("./images/background.png")
if is_alt:
self.rect.y = -SCREEN_RECT.height

def update(self):
# 1.调用父类方法实现
super().update()
# 2. 判断移出屏幕
if self.rect.y >= SCREEN_RECT.height:
self.rect.y = -self.rect.height;

使用:

1
2
3
bg1 = Background()
bg2 = Background(True)
self.back_group = pygame.sprite.Group(bg1, bg2)

把主程序封装成类

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import pygame
from plane_sprites import *


class PlaneGame(object):

def __init__(self):
print("init")
# 1.创建游戏窗口
self.screen = pygame.display.set_mode(SCREEN_RECT.size)
# 2.创建游戏时钟
self.clock = pygame.time.Clock()
# 3.调用私有方法,创建精灵,精灵组
self.__create_sprites()

def __create_sprites(self):
pass

def __event_handler(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
PlaneGame.__game_over()

def __check_collide(self):
pass

def __update_sprites(self):
pass

@staticmethod
def __game_over():
print("Game Over")
pygame.quit()
exit()

def start_game(self):
print("Game Start")
while True:
# 1.设置刷新率
self.clock.tick(FRAME_PER_SECOND)
# 2.事件监听
self.__event_handler()
# 3.碰撞检测
self.__check_collide()
# 4.更新精灵组
self.__update_sprites()
# 5.更新显示
pygame.display.update()


def main():
game = PlaneGame()
game.start_game()


if __name__ == '__main__':
main()

设置敌机

设置计时器
1
2
3
4
5
6
7
8
9
10
# 创建敌机的定时器常量
CREAT_ENEMY_EVENT = pygame.USEREVENT

# 初始化
pygame.time.set_timer(CREAT_ENEMY_EVENT, 1000)

# 调用
elif event.type == CREAT_ENEMY_EVENT:
print("Enemy Created")

敌机类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Enemy(GameSprite):
""" 敌机 """

def __init__(self):
# 1. 调用父类方法,创建敌机精灵,指定图片
super().__init__("./images/enemy1.png")
# 2. 指定速度
self.speed = random.randint(1,3)
# 3. 指定位置
max_x = SCREEN_RECT.width - self.rect.width
self.rect.x = random.randint(0, max_x)
self.rect.bottom = 0

def __del__(self):
print("deleted")

def update(self):
# 1. 调用父类方法,保持垂直飞行
super().update()
# 2. 判断是否飞出屏幕
if self.rect.y >= SCREEN_RECT.height:
print("fly away")
self.kill() # 销毁敌机

英雄类

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
class Hero(GameSprite):
""" 英雄类 """

def __init__(self):
# 1. 调用父类方法
super().__init__("./images/me1.png", 0)
# 2. 设置位置
self.rect.centerx = SCREEN_RECT.centerx
self.rect.bottom = SCREEN_RECT.bottom - 120
# 子弹
self.bullets = pygame.sprite.Group()

def update(self):
# 水平方向移动
self.rect.x += self.speed
# 移除屏幕
if self.rect.right >= SCREEN_RECT.right:
self.rect.right = SCREEN_RECT.right
elif self.rect.x <= 0:
self.rect.x = 0

def fire(self):
# 创建子弹精灵
for i in (0, 1, 2):
bullet = Bullet()
# 设置精灵位置
bullet.rect.bottom = self.rect.y - 20 * i
bullet.rect.centerx = self.rect.centerx
# 添加精灵组
self.bullets.add(bullet)

子弹类

1
2
3
4
5
6
7
8
9
10
11
12
13
class Bullet(GameSprite):
""" 子弹 """

def __init__(self):
# 调用父类方法,设置图片
super().__init__("./images/bullet1.png", -2)

def update(self):
# 调用父类方法,沿垂直方向飞行
super().update()
# 判断子弹飞出屏幕
if self.rect.bottom <= 0:
self.kill()

碰撞检测

1
2
3
4
5
6
7
8
9
10

def __check_collide(self):
# 摧毁敌机
pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)
# 敌机撞毁英雄
enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
# 判断列表是否有内容
if len(enemies) > 0:
self.hero.kill()
self.__game_over()

数据库

数据库分为关系型数据库(SQL)和非关系型数据库(NoSQL)

关系型数据库

关系型数据库是用表单来存储数据的。

行是一条记录。列是一个字段。主键列是唯一表示一条记录的列,比如编号

编程语言是:SQL-结构化查询语言

安装MariaDB

在CentOS的环境下

1
yum install -y mariadb mariadb-server

启动服务

下面可以启动服务

1
systemctl start mariadb

它默认是3306端口,所以可以用下面的命令来检查

1
netstat -nap | grep 3306

可以看到mysqld 占用了这个端口。它的意思是MySQL Daemon是一个守护线程。

Python自动化办公

Python读写excel

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import xlrd
from openpyxl import load_workbook


fileUrl = "D:\\Fyind\\info\\tum\\Semester2\\code\\self\\test.xlsx"

""" xlrd 操作

data = xlrd.open_workbook(fileUrl) # 打开exel表格

table = data.sheets()[0]

nrows = table.nrows
print(table.nrows) #行数

print(table.row(0)) # 第几行

ncols = table.ncols


row0_val = table.row_values(0)
row0_val[0] = 2.0
print(row0_val)
"""

workbook = load_workbook(filename = fileUrl) # 打开表格
sheet = workbook.active # =获取唯一的表
cell = sheet['A1'] # 获取'A1'格子
print(cell.value) # 显示数据
print(cell.row, cell.column, cell.coordinate) # 格子的属性

cell = sheet.cell(row = 1, column= 1) # 第二种方法定位格子

cells = sheet['A1:B5'] # 方形选中

for tpl in cells:
str1 = ""
for cell in tpl:
str1 += str(cell.value) + ' '
print(str1)

# 按行数数
for row in sheet.iter_rows(min_row=2, max_row=3):
for cell in row:
print(cell.value)

sheet['A1'] = 44 # 修改数据
workbook.save(filename=fileUrl) # 保存数据

爬虫

PyQuery

https://pythonhosted.org/pyquery/api.html

数据分析

Numpy

矩阵

创建矩阵

1
2
3
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
a = np.array([[1,0,0],[1,1,1],[1,2,4]],dtype = complex) # 指定类型
a = np.matrix('1,2,3;3,4,5') # 2*3的矩阵

以0填充矩阵

1
2
3
4
print (np.zeros((2,2))) # 2*2
print (np.ones((2,2))) # 1 填充
np.eye(5,5,0) # 填上 5*5 斜对角线1, 从0列开始(单位矩阵)
np.identity(4) # 单位矩阵 4*4

矩阵运算

转置

1
a.T

对应相乘

1
a*b

矩阵乘法

1
np.dot(a,b) # a x b 对应

行列式

1
np.linalg.det(a)

逆矩阵

1
2
3
4
np.linalg.inv(a)

from numpy.linalg import *
inv(a)

多项式

1
2
p = np.array([3,-5,2])
print(np.polyval(p,0.5)) # 多项式求值

求根

1
b = np.roots(p) 

卷积

1
print(np.convolve(p,p))

求导

1
np.polyder(p)