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 4 5 6
| "Hello" + 'world' """ Hello World """ print("Hello"*3)
|
字符串函数
判断类型方法
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) string.endswith(str) string.find(str, start=0, end=len(string)) string.rfind(str,s,e)
|
转换类方法
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) string.rpartition(str) string.spilt(str="",num) string.spiltlines() string.join(seq)
|
输入输出
1 2 3 4 5 6 7 8 9
| print("Hello world") a = input("please input a") print(a+2) print(int(input())+2)
a = 34 b = 12 print("the integer: %06d and the float: %.4lf" % (a, b))
|
类型转换
1 2
| print(int("2333")) float(2)+float("233")
|
变量
全局变量
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()
|
需要使用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 a += [1,2,3] a.sort(reverse=False) print(a[3]) print(a) if 3 in a: print(True) elif 4 not in a: print("4notina") a.append(5) print(len(a)) a.insert(1,2) print(a.index(0)) t = max(a) - min(a) t = list.count(1) a.remove(1) a.reverse() b = list(range(10)) b = list(range(3,8)) b = list(range(5,20,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]
arr[1:-3:2]
arr[::-2]
|
OI控制台输入输出
1 2 3
| if __name__ == '__main__': n = int(sys.stdin.readline())
|
函数
函数传参是类似java的引用传参模式。只有使用方法可以修改外部数据,直接修改引用无效。
1 2 3 4
| def mysum(a, b): return 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
nonlocal m m = 12
in_func() print(n, m) print(list) return in_func """ 10 12 [11, 12, 13] """
|
闭包
- 必须要有内部函数。
- 外部函数有返回值
- 返回值是内部函数
比如上面这个例子就是一个闭包。它可以用来封装函数,可以使得代码简介。下面的函数可以做成一个生产计数器的函数。
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 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()
|
包
可以通过导入包,导入包中所有的模块。但是包里面一定要包含__init__.py的文件
可以这样创建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)
|
使用对象
伪私有方法
_类名__变量 是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 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__)
|
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")
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)) print(g.__next__(), g.__next__()) print(next(g))
|
通过函数定义生成器
1 2 3 4 5 6 7 8
| def func(): n = 0 while True: n += 1 tp = yield n print(tp) g = func() g.send("HH")
|
迭代器
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)
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使用
运行程序
第一次运行程序
如果以后运行,只要按右上角的绿色三角箭头或者Shift+F10快捷键运行就可以了
调整字体大小
File中打开Settings,或者Ctrl+Alt+S打开设置界面
可以再Editor中的Font中改字体和大小。宋体在这里是SimSon,不勾选Show
only monospaced fonts 就可以找到了。
添加函数的注释
把单击一下函数名,然后点左边的灯泡,选插入注释
Ctrl+Q 可以显示详细信息
安装扩展包
Ctrl+Alt+S 打开设置,然后打开Project Interpreter中的pip可以安装包
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()
|
运行后可以看到飞机动起来了
捕获事件
1 2 3 4
| event_list = pygame.event.get() if len(event_list) > 0: print(event_list)
|
可以看到下面捕获到的事件
退出游戏
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): super().update() 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") self.screen = pygame.display.set_mode(SCREEN_RECT.size) self.clock = pygame.time.Clock() 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: self.clock.tick(FRAME_PER_SECOND) self.__event_handler() self.__check_collide() self.__update_sprites() 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): super().__init__("./images/enemy1.png") self.speed = random.randint(1,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): super().update() 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): super().__init__("./images/me1.png", 0) 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
|
启动服务
下面可以启动服务
它默认是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'] 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')
|
以0填充矩阵
1 2 3 4
| print (np.zeros((2,2))) print (np.ones((2,2))) np.eye(5,5,0) np.identity(4)
|
矩阵运算
转置
对应相乘
矩阵乘法
行列式
逆矩阵
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))
|
求根
卷积
求导