== 和 is
== 判断值是否相等 , is判断是否指向的是一个东西
深拷贝 浅拷贝
import copy
c = copy.deepcopy(a) # 完成深拷贝
如果c是引用,引用指向的内容也拷贝(递归)
c = copy.copy(a) # 比deep浅
判断是否是可变类型,如果是不可变类型,不copy,如果是可变类型,只copy一层
进制
bin(18)#0b
oct(18)#0o
hex(18)#0x
int("0x12",16) #到10进制
位运算
& | ^ ~ << >>
私有化
xx
公有变量_xx
单下划线 进制from xx import * ,类对象和子类可以访问__xx
避免和子类命名冲突,子类访问不到(名字重整)__xx__
魔法对象或属性xx_
避免和python关键字冲突
property (属性)
class Test(object):
def __init__(self):
self.__num = 100
def setNum(self, newNum):
print("----setter----")
self.__num = newNum
def getNum(self):
print("----getter----")
return self.__num
num = property(getNum, setNum)
t = Test()
#print(t.__num)
#t.__num = 200
#print(t.getNum())
#t.setNum(50)
#print(t.getNum())
print("-"*50)
t.num = 200 #相当于调用了 t.setNum(200)
print(t.num) #相当于调用了 t.getNum()
#注意点:
#t.num 到底是调用getNum()还是setNum(),要根据实际的场景来判断,
#1. 如果是给t.num赋值 那么一定调用setNum()
#2. 如果是获取t.num的值,那么就一定调用getNum()
#
#property的作用:相当于把方法进行了封装, 开发者在对属性设置数据的时候更方便
=================================================
class Test(object):
def __init__(self):
self.__num = 100
@property
def num(self):
print("----getter----")
return self.__num
@num.setter
def num(self, newNum):
print("----setter----")
self.__num = newNum
t = Test()
t.num = 200 #相当于调用了 t.setNum(200)
print(t.num) #相当于调用了 t.getNum()
import导入模块
搜索路径: sys.path
添加路径 sys.path.append("/home")
重新导入
在程序没退出的情况下 修改模块 新功能不能展示
from imp import *
reload(test)
循环导入
设计一个总模块,分别调用各个模块,防止之间的相互调用,造成循环
迭代器
可迭代对象:
- list tuple dict set str
- generator (生成器)
装饰器
def w1(func):
def inner():
print("--装饰--")
func()
return inner
@w1
def f1():
prinf("----f1-----")
f1()
对有参数的函数装饰
def w1(func):
def inner(a,b): #如果没有ab 会调用失败
print("--执行前装饰--")
func(a,b)
print("--执行后装饰--")
return inner
@w1
def f1(a,b): # 如果函数需要两个参数
prinf("----f1-%d-%d---"%(a,b))
f1()
参数改为*args,**kwargs
def w1(func):
def inner(*args,**kwargs):
print("--执行前装饰--")
func(*args,**kwargs)
print("--执行后装饰--")
return inner
@w1
def f1(a,b):
prinf("----f1-%d-%d---"%(a,b))
f1()
通用装饰器
def w1(func):
def func_in(*args,**kwargs):
ret = func(*args,**kwargs)
return ret
return func_in
@w1
def test():
pass
带有参数的装饰器
def func_arg(arg)
def w1(func):
def func_in():
ret = func()
return func_in
return w1
@func_arg("heihei")
def test():
pass
作用域
命名空间
- globals
- locals
LEGB
locals -> enclosing function -> globals -> builtins
- 局部变量
- 闭包外面的
- 全局
- 内建
动态绑定
import types
class P(object):
def __init__(self.newName):
self.name = newName
def eat(self):
pass
p1.eat = types.MethhodType(eat,p1)
p1.run()
slots
slots = ("name","age") # 限定
生成器
把计算每个元素的方式保存了,不会马上生成,节省了内存
- 把列表生成式的中括号改成小括号
b = (x*2 for x in range(10))
next(b) #0
next(b) #2
next(b) #4
b.__next__() #和上面一样
- 写一个函数 加上yield
- yield的返回值是send的内容
第一次调用需要传none或者先用next
生成器完成多任务
def test1():
while True:
print("---111---")
yield None
def test2():
while True:
print("---222---")
yield None
t1 = test1()
t2 = test2()
while True:
t1.__next__()
t2.__next__()
python 多任务
进程
import os
#ret==0子进程 else父进程
# windows 没有fork函数
pid = os.fork()
os.getpid()
os.getppid()
在windows上可以用的fork
from multiprocessing import Process
import os
#子进程需要执行的代码
def run_proc(name):
print("---子进程---")
if __name__ == '__main__':
print('父进程')
p = Process(target=run_proc,args=('test',))
print('子进程将要执行')
p.start()
p.join() # 等待子进程
print('子程序结束')
进程间通信
from multiprocessing import Queue
q = Queue(3) # 不填3就是无限大
#把q当成参数传入创建进程的函数
p = Process(target=write,arg=(q,))
q.qsize() #0
q.put('haha')
q.qsize() #1
q.get() # 取出添加的第一个
q.empty()
q.full()
q.get_nowait() # 如果为空 报异常(放在try里面)
#-----------
如果是进程池之间通信 应该使用
q.Manager().Queue()
po = Pool()
po.apply(writer,(q,))
po.close()
po.join()
process子类
- 调父类init
- 重写process的run方法
进程池 Pool
from multiprocessing import Pool
def worker(msg):
print(msg)
po = Pool(3) # 定义一个进程池 最大是3
for i in range(0,10):
#po.apply_async(要调用的目标,(传递的参数元组,))
#每次循环警徽用空闲出来的进程去调用目标
po.apply_async(worker(i,))# 非堵塞
po.apply(worker(i,))# 堵塞 几乎不用
po.close() # 关闭进程池,不能添加新的任务
po.join() #主进程等待进程池中执行完才结束
线程 Thread
底层 Thread模块 threading模块对Thread包装
- 函数
import threading
import time
def sayAaa():
print("aaa")
time.sleep(1)
if __name__ = '__main__':
for i in range(5):
t = threading.Thread(target=sayAaa)
t.start()
- 类
import threading
import time
class MyThread(threading.Thread):
def run(self):
for i in range(3):
time.sleep(1)
msg = 'I am '+self.name+' @ '+str(i)
print(msg)
if __name__ == '__main__':
t = MyThread()
t.start()
线程之间共享全局变量
互斥锁
from threading import Thread, Lock
import time
g_num = 0
def test1():
global g_num
#这个线程和test2线程都在抢着 对这个锁 进行上锁,如果有1方成功的上锁,那么导致另外
#一方会堵塞(一直等待)到这个锁被解开为止
for i in range(1000000):
mutex.acquire()
g_num += 1
mutex.release()#用来对mutex指向的这个锁 进行解锁,,,只要开了锁,那么接下来会让所有因为
#这个锁 被上了锁 而堵塞的线程 进行抢着上锁
print("---test1---g_num=%d"%g_num)
def test2():
global g_num
for i in range(1000000):
mutex.acquire()
g_num += 1
mutex.release()
print("---test2---g_num=%d"%g_num)
#创建一把互斥锁,这个锁默认是没有上锁的
mutex = Lock()
p1 = Thread(target=test1)
p1.start()
#time.sleep(3) #取消屏蔽之后 再次运行程序,结果会不一样,,,为啥呢?
p2 = Thread(target=test2)
p2.start()
print("---g_num=%d---"%g_num)
同步
from threading import Thread,Lock
from time import sleep
class Task1(Thread):
def run(self):
while True:
if lock1.acquire():
print("------Task 1 -----")
sleep(0.5)
lock2.release()
class Task2(Thread):
def run(self):
while True:
if lock2.acquire():
print("------Task 2 -----")
sleep(0.5)
lock3.release()
class Task3(Thread):
def run(self):
while True:
if lock3.acquire():
print("------Task 3 -----")
sleep(0.5)
lock1.release()
#使用Lock创建出的锁默认没有“锁上”
lock1 = Lock()
#创建另外一把锁,并且“锁上”
lock2 = Lock()
lock2.acquire()
#创建另外一把锁,并且“锁上”
lock3 = Lock()
lock3.acquire()
t1 = Task1()
t2 = Task2()
t3 = Task3()
t1.start()
t2.start()
t3.start()
ThreadLocal
import threading
# 创建全局ThreadLocal对象:
local_school = threading.local()
def process_student():
# 获取当前线程关联的student:
std = local_school.student
print('Hello, %s (in %s)' % (std, threading.current_thread().name))
def process_thread(name):
# 绑定ThreadLocal的student:
local_school.student = name
process_student()
t1 = threading.Thread(target= process_thread, args=('dongGe',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('老王',), name='Thread-B')
t1.start()
t2.start()
异步、回调
from multiprocessing import Pool
import time
import os
def test():
print("---进程池中的进程---pid=%d,ppid=%d--"%(os.getpid(),os.getppid()))
for i in range(3):
print("----%d---"%i)
time.sleep(1)
return "hahah" #返回给了父进程
def test2(args):
print("---callback func--pid=%d"%os.getpid()) #是父进程做的
print("---callback func--args=%s"%args)
pool = Pool(3)
pool.apply_async(func=test,callback=test2)
#异步的理解:主进程正在做某件事情,突然 来了一件更需要立刻去做的事情,
#那么这种,在父进程去做某件事情的时候 并不知道是什么时候去做,的模式 就称为异步
while True:
time.sleep(1)
print("----主进程-pid=%d----"%os.getpid())
GIL
Python的线程是假的
解决方式: 用C语言写
loop.c
void DeadLoop()
{
while(1)
{
;
}
}
main.py
from ctypes import *
from threading import Thread
#加载动态库
lib = cdll.LoadLibrary("./libdeadloop.so")
#创建一个子线程,让其执行c语言编写的函数,此函数是一个死循环
t = Thread(target=lib.DeadLoop)
t.start()
#主线程,也调用c语言编写的那个死循环函数
#lib.DeadLoop()
while True:
pass
gcc xxx.c -shared -o libxxxx.so
python3网络编程
TCP/IP
- 应用层 (应用层 表示层 会话层)
- 传输层 TCP UDP
- 网络层 IP ICMP ARP RARP
- 链路层(物理层 数据链路层)
端口号:0-65535
知名端口0-1023
动态端口1024-65535
IP地址
- 0和255不能用(0网络号 255广播)
- D类多播
参考资料:菜鸟教程
socket函数创建
socket.socket([family[, type[, proto]]])
- family: 套接字家族可以使AF_UNIX或者AF_INET
- type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM或SOCK_DGRAM
- protocol: 一般不填默认为0.
例如:
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server TCP
#!/usr/bin/python3
# 文件名:server.py
import socket
# 创建 socket 对象
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 获取本地主机名
host = socket.gethostname()
port = 9999
# 绑定端口号
serversocket.bind((host, port))
# 设置最大连接数,超过后排队
serversocket.listen(5)
while True:
# 建立客户端连接
clientsocket, addr = serversocket.accept()
print("连接地址: %s" % str(addr))
msg = '欢迎访问菜鸟教程!' + "\r\n"
clientsocket.send(msg.encode('utf-8'))
clientsocket.close()
client TCP
#!/usr/bin/python3
# 文件名:client.py
import socket
# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 获取本地主机名
host = socket.gethostname()
port = 9999# 设置端口号
s.connect((host, port))# 连接服务,指定主机和端口
msg = s.recv(1024) # 接收小于 1024 字节的数据
s.close()
print (msg.decode('utf-8'))
UDP server
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("127.0.0.1", 6000))
print("UDP bound on port 6000...")
while True:
data, addr = s.recvfrom(1024)
print("Receive from %s:%s" % addr)
print(data)
if data == b"exit":
s.sendto(b"Good bye!\n", addr)
continue
s.sendto(b"Hello %s!\n" % data, addr)
UDP client
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addr = ("127.0.0.1", 6000)
while True:
data = input("Please input your name: ")
if not data:
continue
s.sendto(data.encode(), addr)
response, addr = s.recvfrom(1024) # 收到的是个元组
print(response.decode())
if data == "exit":
print("Session is over from the server %s:%s\n" % addr)
break
s.close()
SocketServer类
class ForkingUDPServer(ForkingMixIn, UDPServer)
class ForkingTCPServer(ForkingMixIn, TCPServer)
class ThreadingUDPServer(ThreadingMixIn, UDPServer)
class ThreadingTCPServer(ThreadingMixIn, TCPServer)
class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer)
class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer)
socketserver TCP Server
import socketserver
class MyTcpHandler(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
data = self.request.recv(1024)
if not data: break # 此行代码针对linux系统
self.request.send(data.upper())
print(data)
except ConnectionResetError:
break
self.request.close()
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('0.0.0.0', 8180), MyTcpHandler)
server.serve_forever()
socketserver TCP Client
from socket import *
import os ,time
client = socket(AF_INET, SOCK_STREAM)
client.connect(('118.24.137.128', 8180))
while True:
msg = '%s hello' % os.getpid()
client.send(msg.encode("utf-8"))
data = client.recv(1024)
print(data.decode('utf-8'))
time.sleep(1)
socketserver UDP Server
import socketserver
class MyUdpHandler(socketserver.BaseRequestHandler):
def handle(self):
res=self.request[0]
print('客户端发来的数据:',res)
self.request[1].sendto(res.upper(),self.client_address)
if __name__ == '__main__':
server=socketserver.ThreadingUDPServer(('0.0.0.0',8888),MyUdpHandler)
server.serve_forever()
socketserver UDP Client
from socket import *
import os, time
client = socket(AF_INET, SOCK_DGRAM)
while True:
msg = '%s hello' % os.getpid()
client.sendto(msg.encode('utf-8'), ('118.24.137.128', 8888))
data, server_addr = client.recvfrom(1024)
print(data.decode('utf-8'))
time.sleep(1)
END
参考资料
- python3学习笔记 图书馆TP311.561 143:1
- 网页: 菜鸟教程 -- 学习python3
一些零碎代码
UART py
# -*- coding: utf-8 -*
import serial
import time
# 打开串口
ser = serial.Serial("/dev/ttyUSB0", 115200)
def main():
while True:
# 获得接收缓冲区字符
count = ser.inWaiting()
if count != 0:
# 读取内容并回显
recv = ser.read(count)
print(recv)
#ser.write(recv)
# 清空接收缓冲区
ser.flushInput()
# 必要的软件延时
time.sleep(0.2)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
if ser != None:
ser.close()