工厂方法模式:基类定义接口,子类具体实现
class Store(object):
#此处选车并不会执行
def select_car(self):
print("Store:select_car")
# 店铺只负责订购功能,添加选车接口
def order(self, car_type):
return self.select_car(car_type)
class BMW_Car_Store(Store):
#继承基类,实现自己的选车方案,即调用工厂类
def select_car(self, car_type):
return BMW_Factory().select_car_by_type(car_type)
class BMW_Factory(object):
#被调用类的最终选车实现
def select_car_by_type(self, car_type):
print("BMW_Factory in BMW_Car_Store")
bmw_store = BMW_Car_Store()
bmw = bmw_store.order("720li")
tcp server
from socket import *
#创建服务器套接字,绑定ip端口,监听(被动连接)数量
svr_skt = socket(AF_INET, SOCK_STREAM)
svr_skt.bind(('',7789))
svr_skt.listen(4)
#创建服务器接收到待客户端(阻塞,等客户端连入),及其ip和port
clt_skt, clt_info = svr_skt.accept()
#接收数据
recv_data = clt_skt.recv(1024)
print str(clt_info)+':'+str(recv_data)
#发送数据,将字符串中文编码
#svr_skt.send('hello xp'.encode('gb2312'))
#此处send数据报错:socket.error: [Errno 32] Broken pipe
#关闭客户端,再服务器
clt_skt.close()
svr_skt.close()
tcp client
from socket import *
#创建套接字,绑定服务器端口
clt_skt = socket(AF_INET, SOCK_STREAM)
clt_skt.connect(('192.168.37.3',8989))
#连接后即发送信息,此处c发给s成功,而s发给c失败
clt_skt.send('hello xp'.encode('gb2312'))
#接收数据
rcv_data = clt_skt.recv(1024)
print(rcv_data)
#关闭套接字
clt_skt.close()
udp receive & send
from socket import *
#创建套接字,绑定接收ip和端口
udp_skt = socket(AF_INET, SOCK_DGRAM)
bind_addr = ('',7788)
udp_skt.bind(bind_addr)
#输入待发送信息,发送
send_info = raw_input('input infomation to send:')
udp_skt.sendto(str(send_info),('192.168.37.3',8080))
#等待接收信息,
recv_data = udp_skt.recvfrom(1024)
print str(recv_data[1])+':'+recv_data[0]
#关闭套接字
udp_skt.close()
创建单例对象
Python 中的单例模式
使用模块, new,装饰器(decorator),元类(metaclass)实现单例模式
class Dog(object):
#实例创建次数标识,初始化传参标识
__instance = None
__init_flag = False
# 只初始化一次对象
def __init__(self, name):
if Dog.__init_flag == False:
self.name = name
Dog.__init_flag = True
def __new__(cls, name):
# 创建单例对象
if cls.__instance == None:
cls.__instance = object.__new__(cls)
return cls.__instance
else:
return cls.__instance
# 创建第一个
q = Dog("q")
print(q.name)
print(id(q))
# 创建第二个
r = Dog("r")
print(id(q), id(r))
print(q.name, r.name)
老王开枪
# ========gunner shoot=========
class Person(object):
"""docstring for Person"""
def __init__(self, name):
super(Person, self).__init__()
self.name = name
self.gun = None # storage cite of gun object 存储枪对象引用
self.power = 100
def setup_bullet(self, clip, bullet):
# setup clip with bullets
clip.save_bullet(bullet)
def setup_clip(self, gun, clip):
#setup gun with clip
gun.save_clip(clip)
def pick_gun(self, gun):
#pick up gun
self.gun = gun
def shoot(self, target):
# with gun
self.gun.fire(target)
def hurted(self, kill_ability):
self.power -= kill_ability
def __str__(self):
# if one has gun, return his power
if self.gun:
return "{0}\'s power is {1}, {2}".format(self.name, self.power, self.gun)
else:
if self.power > 0:
return "{0}\'s power is {1}, no gun".format(self.name, self.power)
else:
return "{0}\'s killed".format(self.name)
class Gun(object):
"""docstring for Gun"""
def __init__(self, name):
super(Gun, self).__init__()
self.name = name
self.clip = None
def save_clip(self, clip):
self.clip = clip
def fire(self, target):
# bullet out from clip 子弹出弹夹
bullet = self.clip.popup()
# if has bullet, then hit target 如果弹夹非空,射击敌人
if bullet:
bullet.hit(target)
else:
print("no bullet")
def __str__(self):
if self.clip:
return "gun info: {0}, {1}".format(self.name, self.clip)
else:
return "gun info: {0}, no clip".format(self.name)
class Clip(object):
"""docstring for Clip"""
def __init__(self, max_num):
super(Clip, self).__init__()
self.max_num = max_num # max num of clip 弹夹最大容量
self.bullet_list = [] # storage cite of bullet object 存储子弹对象的引用
def save_bullet(self, bullet):
# push bullet into clip # 将子弹压入弹夹
self.bullet_list.append(bullet)
def popup(self):
# clip popup upest bullet, if no bullet, return None 弹夹弹出子弹
if self.bullet_list:
return self.bullet_list.pop()
else:
return None
def __str__(self):
return "clip info: {0}/{1}".format(len(self.bullet_list), self.max_num)
class Bullet(object):
"""docstring for Bullet"""
def __init__(self, kill):
super(Bullet, self).__init__()
# kill ability 杀伤力
self.kill = kill
def hit(self, target):
# target lose life power value: kill 敌人失去生命力值: 杀伤力
target.hurted(self.kill)
def main():
# 1.gunner 枪手
gunner = Person("gunner")
# 2.gun 枪
ak47 = Gun("ak47")
# 3.clip 弹夹
clip = Clip(20)
# 4.create some bullets 创建一些子弹
# setup clip with these bullets 将这些子弹装入弹夹
for i in range(10):
# bullet with kill_ability 子弹,带杀伤力
bullet = Bullet(10)
# setup_bullet 装子弹
gunner.setup_bullet(clip, bullet)
# 4.setup_clip 装弹夹
gunner.setup_clip(ak47, clip)
# 5.pick_gun 拿枪
gunner.pick_gun(ak47)
# test clip info 测试信息
# print(clip)
# test gun info
# print(ak47)
# test gunner object
print(gunner)
# 6.target 敌人
target = Person("target")
print(target)
# 7.shoot_target in 12 times 射击12次
for i in range(12):
gunner.shoot(target)
print(target)
print(gunner, end="\n\n")
if __name__ == '__main__':
main()
飞机大战
from pygame.locals import *
import pygame
import time
import random
class Base(object):
# 抽取坐标,屏幕,图片路径
def __init__(self, x, y, screen, image):
self.x = x
self.y = y
self.screen = screen
self.image = pygame.image.load(image)
class BasePlane(Base):
def __init__(self, x, y, screen, image):
Base.__init__(self, x, y, screen, image)
self.bullets = []
# 抽取飞机对象显示
def display(self):
self.screen.blit(self.image, (self.x, self.y))
# 存储越界子弹,并存储到待删除子弹列表,然后全删掉
del_bullets = []
for bullet in self.bullets:
bullet.display()
bullet.move()
if bullet.judge():
del_bullets.append(bullet)
for del_bullet in del_bullets:
self.bullets.remove(del_bullet)
class Plane(BasePlane):
def __init__(self, screen):
BasePlane.__init__(self, 230, 600, screen, "./image/qq.jpg")
def to_left(self):
self.x -= 20
def to_right(self):
self.x += 10
def fire(self):
bullet = Bullet(self.screen, self.x, self.y)
self.bullets.append(bullet)
class Enemy(BasePlane):
def __init__(self, screen):
BasePlane.__init__(self, 230, 30, screen, "./image/Icon-114.png")
self.diret = "left"
def move(self):
if self.diret == "left":
self.x -= 5
elif self.diret == "right":
self.x += 5
if self.x > 400:
self.diret = "left"
elif self.x < 20:
self.diret = "right"
# break
def fire(self):
# 非连续开火
random_num = random.randint(1, 100)
if random_num == 2 or random_num == 1:
bullet_enemy = BulletEnemy(self.screen, self.x, self.y)
self.bullets.append(bullet_enemy)
class BaseBullet(Base):
def __init__(self, x, y, screen, image):
Base.__init__(self, x, y, screen, image)
def display(self):
self.screen.blit(self.image, (self.x, self.y))
class Bullet(BaseBullet):
def __init__(self, screen, x, y):
BaseBullet.__init__(self, x+12, y-20, screen, "./button_green.9.png")
def move(self):
self.y -= 50
def judge(self):
if self.y < 100:
return True
else:
return False
class BulletEnemy(BaseBullet):
def __init__(self, screen, x, y):
BaseBullet.__init__(self, x+40, y+120, screen, "./button_red.9.png")
def move(self):
self.y += 10
def judge(self):
if self.y > 500:
return True
else:
return False
def key_ctrl(plane):
for event in pygame.event.get():
# 退出
if event.type == pygame.QUIT:
print("exit")
exit(0)
elif event.type == KEYDOWN:
if event.key == K_a or event.key == K_LEFT:
print("left")
plane.to_left()
elif event.key == K_d or event.key == K_RIGHT:
print("right")
plane.to_right()
elif event.key == K_SPACE:
print("space")
plane.fire()
def main():
# 创建窗口,背景图片
screen = pygame.display.set_mode((512, 768), 0, 32)
bg = pygame.image.load("./image/img_bg_level_1.jpg")
# 创建飞机,敌机
plane = Plane(screen)
enemy = Enemy(screen)
while True:
# 显示背景,我机,敌机
screen.blit(bg, (0, 0))
plane.display()
enemy.display()
# 刷新显示数据到屏幕
pygame.display.update()
# 敌机移动,开火
enemy.move()
enemy.fire()
# 控制我机
key_ctrl(plane)
time.sleep(0.01)
# pygame.quit()
if __name__ == '__main__':
main()
单进程非阻塞tcp server
# tcp_server, one thread, no block
from socket import *
# create socket, reuse port
server_sock = socket(AF_INET, SOCK_STREAM)
server_sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# bind ip, port
local_addr = ('', 7777)
server_sock.bind(local_addr)
# set not block
server_sock.setblocking(False)
# listen socket
server_sock.listen(5)
client_ls = []
while True:
# waiting new client come
try:
client_sock, client_addr = server_sock.accept()
# BlockingIOError
except:
pass
else:
print("new client:{0}".format(client_addr))
# set not block
client_sock.setblocking(False)
# storage cite of client info
client_ls.append((client_sock, client_addr))
for client_sock, client_addr in client_ls:
try:
data = client_sock.recv(1024)
except:
pass
else:
if len(data) > 0:
print("{0} : {1}".format(str(client_addr), data.decode('gb2312')))
else:
client_sock.close()
# maybe bug
client_ls.remove((client_sock, client_addr))
print("{0} offline".format(client_addr))、
静态文件的Web服务器代码
# coding=utf-8
# static web server
import re
import socket
from multiprocessing import Process
# 定义发送文件根目录
HTML_ROOT_DIR = "./html"
def main():
tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_sock.bind(("", 7777))
tcp_sock.listen(128)
tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
while True:
cli_sock, cli_addr = tcp_sock.accept()
print("[{0}] 用户已连接...".format(cli_addr))
cli_process = Process(target=handle_cli, args=(cli_sock,))
cli_process.start()
# socket 传入线程后关闭? 不明白
cli_sock.close()
def handle_cli(cli_sock):
"""handle client requests"""
# 获取数据,decode为字符串
request_data = cli_sock.recv(1024).decode("utf-8")
# print("requested: ", request_data)
request_lines = request_data.splitlines()
for line in request_lines:
print("=======", line)
# 正则解析报文,提取请求文件名 "GET / HTTP/1.1"
# 下面在第二次网页连入时,IndexError: list index out of range
response_start_line = request_lines[0]
file_name = re.match(r"\w+\s+(/[^\s]*)\s", response_start_line).group(1)
# 设置主页默认文件
if file_name == "/":
file_name = "/simple_html.html"
try:
with open(HTML_ROOT_DIR + file_name, "rb") as file:
# 此处decode为字符串,否则浏览器收到数据为字节形式
file_data = file.read().decode("utf-8")
except IOError as e:
# 构造失败响应数据,符合HTTP规范
response_start_line = "HTTP/1.1 404 not found\r\n"
response_headers = "Server: My server\r\n"
response_body = "file not found"
else:
# 构造成功响应数据,符合HTTP规范
response_start_line = "HTTP/1.1 200 OK\r\n"
response_headers = "Server: My server\r\n"
response_body = file_data
response = response_start_line + response_headers + "\r\n" + response_body
print("response: ", response)
# 发送响应数据
cli_sock.send(response.encode("utf-8"))
# 发送后关闭客户端
cli_sock.close()
if __name__ == '__main__':
main()
动态Web服务器,待完善
# coding=utf-8
# dynamic web server
import socket
from multiprocessing import Process
import re
import sys
# 发送文件根目录
HTML_ROOT_DIR = "./html"
WSGI_PYTHON_DIR = "./html"
class HTTPServer(object):
def __init__(self):
self.tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
def bind(self, port):
self.tcp_sock.bind(("", port))
def start(self):
self.tcp_sock.listen(128)
while True:
cli_sock, cli_addr = self.tcp_sock.accept()
print("[{0}] 用户已连接...".format(cli_addr))
cli_process = Process(target=self.handle_cli, args=(cli_sock,))
cli_process.start()
# socket 传入线程后关闭? 不明白
cli_sock.close()
def start_response(self, status, headers):
"""status = "200 OK"
headers = [
("Content_Type", "text/plain")
]
"""
response_headers = "HTTP/1.1" + status + "\r\n"
for header in headers:
response_headers += "%s:%s\r\n" % header
self.response_headers = response_headers
def handle_cli(self, cli_sock):
"""handle client requests"""
# 获取数据,decode为字符串
request_data = cli_sock.recv(1024).decode("utf-8")
# print("requested: ", request_data)
request_lines = request_data.splitlines()
# for line in request_lines:
# print("=======", line)
# 正则解析报文,提取请求
response_start_line = request_lines[0]
file_name = re.match(r"\w+\s+(/[^\s]*)\s", response_start_line).group(1)
method = re.match(r"(\w+)\s+/[^\s]*\s", response_start_line).group(1)
param = re.match(r"person=(\w+)", response_start_line)#.group(1)
print(response_start_line)
print(param)
env = {
"PATH_INFO": file_name,
"METHOD": method,
"QUERY_STRING": param
}
if file_name.endswith(".py"):
# 处理为动态信息
# 导入请求模块, 返回值加入返回体
m = __import__(file_name[1:-3])
response_body = m.application(env, self.start_response)
response = self.response_headers + "\r\n" + response_body
else:
# 处理为静态信息
# 第二次请求为页码头的图标,出现异常,这里也归为显示主页
if file_name == "/" or file_name == "/favicon.ico":
file_name = "/simple_html.html"
try:
with open(HTML_ROOT_DIR + file_name, "rb") as file:
# 此处decode为字符串,否则浏览器收到数据为字节形式
file_data = file.read().decode("utf-8")
except IOError as e:
# 构造失败响应数据,符合HTTP规范
response_start_line = "HTTP/1.1 404 not found\r\n"
response_headers = "Server: My server\r\n"
response_body = "file not found"
else:
# 构造成功响应数据,符合HTTP规范
response_start_line = "HTTP/1.1 200 OK\r\n"
response_headers = "Server: My server\r\n"
response_body = file_data
response = response_start_line + response_headers + "\r\n" + response_body
# print("response: ", response)
# 发送响应数据
cli_sock.send(response.encode("utf-8"))
# 发送后关闭客户端
cli_sock.close()
def main():
sys.path.insert(1, WSGI_PYTHON_DIR)
http = HTTPServer()
http.bind(8000)
http.start()
if __name__ == '__main__':
main()
列表各方法运行时间测试
import time, timeit
def test1():
ls = []
for i in range(10000):
ls.append(i)
def test2():
ls = []
for i in range(10000):
ls += [i]
def test3():
ls =[i for i in range(10000)]
def test4():
ls = list(range(10000))
def test5():
ls = []
for i in range(10000):
ls.extend([i])
def test6():
ls = []
for i in range(10000):
ls.insert(0, i)
timer1 = timeit.Timer('test1()', 'from __main__ import test1')
timer2 = timeit.Timer('test2()', 'from __main__ import test2')
timer3 = timeit.Timer('test3()', 'from __main__ import test3')
timer4 = timeit.Timer('test4()', 'from __main__ import test4')
timer5 = timeit.Timer('test5()', 'from __main__ import test5')
timer6 = timeit.Timer('test6()', 'from __main__ import test6')
print(timer1.timeit(1000))
print(timer2.timeit(1000))
print(timer3.timeit(1000))
print(timer4.timeit(1000))
print(timer5.timeit(1000))
print(timer6.timeit(1000))
栈,list实现
class Stack(object):
"""docstring for Stack"""
def __init__(self):
self.__ls = []
def push(self, item):
self.__ls.append(item)
def pop(self):
if self.__ls:
return self.__ls.pop()
else:
return None
def peek(self):
if self.__ls:
return self.__ls[-1]
else:
return None
def is_empty(self):
return self.__ls == []
def size(self):
return len(self.__ls)
if __name__ == '__main__':
stack = Stack()
stack.push(2)
stack.push(3)
print(stack.pop())
print(stack.pop())
print(stack.pop())
单向链表,删除最复杂。。。
class Node(object):
"""docstring for Node"""
def __init__(self, elem):
self.elem = elem
self.next = None
class SingleLinkList(object):
"""docstring for SingleLinkList"""
def __init__(self, node=None):
self._head = node
def is_empty(self):
return self._head == None
def length(self):
cur = self._head
count = 0
while cur != None:
count += 1
cur = cur.next
return count
def travel(self):
cur = self._head
while cur != None:
print(cur.elem, end=" ")
cur = cur.next
def add(self, item):
node = Node(item)
node.next = self._head
self._head = node
def append(self, item):
node = Node(item)
# 如果为空
if self.is_empty():
self._head = node
else:
# 如果非空
cur = self._head
while cur.next != None:
cur = cur.next
cur.next = node
def insert(self, pos, item):
node = Node(item)
# 如果在列表索引范围外,则插入头、尾部
if pos > self.length()-1:
self.append(item)
elif pos > 0:
cur = self._head
count = 0
while count < pos - 1:
cur = cur.next
count += 1
# cur最终指向pos-1位置节点
node.next = cur.next
cur.next = node
else:
self.add(item)
def remove(self, item):
cur = self._head
pre = None
while cur != None:
if cur.elem == item:
if cur == self._head:
self._head = cur.next
else:
pre.next = cur.next
break
else:
pre = cur
cur = cur.next
def search(self, item):
cur = self._head
count = 0
while cur != None:
if cur.elem == item:
return count
else:
count += 1
cur = cur.next
return -1
if __name__ == '__main__':
sll = SingleLinkList()
# print(sll.is_empty())
# print(sll.length())
#
sll.append(10)
sll.append(20)
sll.add(30)
# sll.add(40)
# print(sll.length())
sll.travel()
sll.remove(30)
sll.travel()
单向循环链表
class Node(object):
"""docstring for Node"""
def __init__(self, elem):
self.elem = elem
self.next = None
class SingleCycleLinkList(object):
"""docstring for SingleLinkCycleList"""
def __init__(self, node=None):
self._head = node
# 指向头部
if node:
node.next = self._head
def is_empty(self):
return self._head == None
def length(self):
if self.is_empty():
return 0
cur = self._head
count = 1
while cur.next != self._head:
count += 1
cur = cur.next
return count
def travel(self):
if self.is_empty():
return
cur = self._head
while cur.next != self._head:
print(cur.elem, end=" ")
cur = cur.next
# 打印尾结点元素
print(cur.elem)
def add(self, item):
node = Node(item)
if self.is_empty():
self._head = node
node.next = self._head
else:
# cur保存尾结点
cur = self._head
while cur.next != self._head:
cur = cur.next
node.next = self._head
self._head = node
# 尾结点重新指向头/node结点
cur.next = self._head
def append(self, item):
node = Node(item)
# 如果为空
if self.is_empty():
self._head = node
node.next = self._head
else:
# 如果非空
cur = self._head
while cur.next != self._head:
cur = cur.next
node.next = self._head
cur.next = node
def insert(self, pos, item):
node = Node(item)
# 如果在列表索引范围外,则插入头、尾部
if pos > self.length()-1:
self.append(item)
elif pos > 0:
cur = self._head
count = 0
while count < pos - 1:
cur = cur.next
count += 1
# cur最终指向pos-1位置节点
node.next = cur.next
cur.next = node
else:
self.add(item)
def remove(self, item):
"""没有返回值"""
# 指向头结点和None
cur = self._head
pre = None
while cur.next != self._head:
if cur.elem == item:
# 删除头结点的情况
if cur == self._head:
# 寻找尾结点
rear = self._head
while rear.next != self._head:
rear = rear.next
self._head = cur.next
rear.next = self._head
# 删除中间结点
else:
pre.next = cur.next
# 删除掉就返回
return
else:
pre = cur
cur = cur.next
# 删除尾结点的情况,此时退出循环,
# cur指向尾结点,cur.next指向头结点
if cur.elem == item:
# 结点只有一个
if cur == self._head:
self._head == None
# 节点数超过一个
else:
pre.next = cur.next
def search(self, item):
if self.is_empty():
return -1
cur = self._head
count = 0
while cur.next != self._head:
if cur.elem == item:
return count
else:
count += 1
cur = cur.next
# 判断尾结点
if cur.elem == item:
return count
# 如果不存在
return -1
if __name__ == '__main__':
sll = SingleCycleLinkList()
# print(sll.is_empty())
# print(sll.length())
sll.append(10)
sll.append(20)
sll.append(30)
sll.travel()
sll.remove(10)
sll.travel()
双向链表
class Node(object):
"""docstring for Node"""
def __init__(self, elem):
self.elem = elem
self.next = None
self.prev = None
class DoubleLinkList(object):
"""docstring for SingleLinkList"""
def __init__(self, node=None):
self._head = node
def is_empty(self):
return self._head is None
def length(self):
cur = self._head
count = 0
while cur:
count += 1
cur = cur.next
return count
def travel(self):
cur = self._head
while cur:
print(cur.elem, end=" ")
cur = cur.next
def add(self, item):
node = Node(item)
node.next = self._head
self._head = node
node.next.prev = node
def append(self, item):
node = Node(item)
# 如果为空
if self.is_empty():
self._head = node
else:
# 如果非空
cur = self._head
while cur.next:
cur = cur.next
cur.next = node
node.prev = cur
def insert(self, pos, item):
# 如果在列表索引范围外,则插入头、尾部
if pos > self.length()-1:
self.append(item)
elif pos > 0:
cur = self._head
count = 0
while count < pos:
cur = cur.next
count += 1
# cur最终指向pos位置节点
node = Node(item)
# 先把node节点的前后指针,指向cur前后节点
# 再打断cur前节点的后指针,指向node
# 最后打断cur节点的前指针,指向node
node.next = cur
node.prev = cur.prev
cur.prev.next = node
cur.prev = node
else:
self.add(item)
def remove(self, item):
cur = self._head
while cur:
if cur.elem == item:
if cur == self._head:
self._head = cur.next
# 如果链表只有cur一个节点
if cur.next:
cur.next.prev = None
else:
cur.prev.next = cur.next
# 如果cur是链表最后一个节点
if cur.next:
cur.next.prev = cur.prev
break
else:
cur = cur.next
def search(self, item):
cur = self._head
count = 0
while cur:
if cur.elem == item:
return count
else:
count += 1
cur = cur.next
return -1
if __name__ == '__main__':
dll = DoubleLinkList()
print(dll.is_empty())
print(dll.length())
dll.append(10)
dll.append(20)
dll.append(30)
dll.add(0)
dll.travel()
dll.remove(0)
dll.travel()
print(dll.length())