#liunx创建虚拟环境 python3.3以上用法
# 创建一个项目文件夹,然后创建一个虚拟环境。创建完成后项目文件夹中会有一个 venv 文件夹
$ mkdir myproject
$ cd myproject
$ python3 -m venv venv
$ . venv/bin/activate #激活相应的虚拟环境
$ pip3 install ...等操作
$ pip3 freeze > requirements.txt #导出虚拟环境依赖到requirements.txt(须在虚拟环境中)
$ pip install -r requirements.txt #安装虚拟环境依赖包(须在虚拟环境中)
$ deactivate #退出虚拟环境
-------------------------
生成器表达式(节省内存)
value = ('小鸟 %s' % i for i in range(10) if i % 2)
print(next(value))
>小鸟 1
---------------------------------------------------
取开头结尾
arr = [x for x in range(11)]
a, *_, d = arr
print(a, d)
# 0 10
---------------------------------------------------
logging日志模块
import logging
# logging.basicConfig(
# level=logging.DEBUG,
# filename="log.log",
# filemode='w',
# format="%(asctime)s %(filename)s [%(lineno)d] %(message)s"
# )
logger = logging.getLogger('myLog')
logger.setLevel('DEBUG')
fh = logging.FileHandler('log.txt', encoding="utf-8")
ch = logging.StreamHandler()
fm = logging.Formatter("[%(name)s] %(asctime)s {%(levelname)s} %(message)s")
fh.setFormatter(fm)
ch.setFormatter(fm)
logger.addHandler(fh)
logger.addHandler(ch)
logger.debug('老铁666')
#日志管理库 loguru ( 安装 pip install loguru )
import os
from loguru import logger
path=os.path.dirname(__file__) #当前目录
#配置 (format 设置格式,rotation='10 MB' 文件大小,encoding='utf8' 编码)
logger.add(os.path.join(path,'log','file_log.log'),level="DEBUG",format='{time:YYYY-MM-DD HH:mm:ss} | {level} | {file} | {message}',rotation='10 MB',encoding='utf8')
#装饰器捕获错误保存到日志里
@logger.catch
def my_function():
pass
logger.info('测试日志了')
logger.debug('debug测试')
logger.warning('警告测试')
logger.error("错误信息")
logger.critical("最高警告")
官方文档:https://loguru.readthedocs.io/en/stable/overview.html
--------------------------------------------------
import configparser
config = configparser.ConfigParser()
# 增
# config['head'] = {
# 'name': 'xiaoMing',
# 'age': 11,
# 'sex': 'girl'
# }
#
# with open('config.txt', 'w', encoding='utf-8') as f:
# config.write(f)
# config.write(open('config.txt', 'w', encoding='utf-8'))
# 查
config.read('config.txt',encoding='utf-8')
# print(config['head']['name'])
# name = input('模块名 =>')
# if name in config.sections():
# print(config.options(name))
# print(dict(config.items(name)))
# config.add_section('new')
config.set('new', 'name', 'shui')
config.write(open('config.txt', 'w'))
-----------------------------------------------
import hashlib
def getMd5(v):
return hashlib.md5(('my %s' % v).encode('utf-8')).hexdigest()
print(getMd5(111))
------------------------------------------------
class Show:
"""这是一个类的静态属性及方法"""
name = 'xioaming'
def __init__(self, age, sex):
self.age = True if age > 10 else False
self.sex = sex
print(self)
@property
def f(self):
return self._arr
@f.setter
def f(self, v):
self._arr = v * 2
@classmethod
def show(cls, v):
print(cls.name, v)
@staticmethod
def s():
print(444)
#属性get触发
def __getattr__(self, item):
print(item)
#属性del触发
def __delattr__(self, item):
print(item)
#属性set触发, 注意:需要下面这种赋值否则报错
def __setattr__(self, key, value):
#加入到字典中
self.__dict__[key] = value
x = Show(11, 'girl')
x.f = 11
print(x.f)
Show.show(22)
Show.s()
print(getattr(x, 'age', None))
-------------------------------------------
import abc
# 接口继承,子类必须实现父类定义的方法
class Show(metaclass=abc.ABCMeta):
"""这是一个接口继承类"""
@abc.abstractmethod
def read(self):
pass
class Child(Show):
age = 11
def __init__(self):
pass
def read(self):
print(666)
cla = Child()
----------------------------------------------
类的继承从左往右,上级线性查找,找不到在从调用类从头从左往右,上级线性查找
类的方法
class test:
name = 11
def __init__(self, name):
self.name = name
def show(self, v):
print('输入的百分比是 %s %%' % v)
a = test('xiaohong')
if hasattr(a, 'age'):
print(getattr(a, 'age', None))
else:
setattr(a, 'age', 12)
print(getattr(a, 'age', 'error age'))
delattr(a, 'age')
print(getattr(a, 'age', 'error age'))
print(hasattr(a, 'show1'))
getattr(a, 'show')(123)
--------------------------------------------------
import os
print(os.path.dirname(os.path.dirname(__file__))) #当前目录
#设置执行目录
import os, sys
PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(PATH)
---------------------------------------------------
class Open:
'上下文管理协议 __enter__ , __exit__'
def __init__(self,name):
self.name=name
def __enter__(self):
print('start')
#返回值给 f
return self
def __exit__(self,exc_type,exc_val,exc_tb):
print("exit")
#exc_type,exc_val,exc_tb是异常报错的返回信息
#return True 这个可以忽略异常继续运行
with Open("wo") as f:
print(f.name)
--------------------------------------------------------------
#socketserver用法
import socketserver
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
print('conn',self.request,self)
print('addr',self.client_address)
while True:
try:
#收消息
data=self.request.recv(1024)
if not data:break
print('收到客户端消息:',data.decode("utf-8"))
#发消息
self.request.sendall(data)
except Exception as e:
print('error:',e)
break
if __name__=='__main__':
s=socketserver.ThreadingTCPServer(('127.0.0.1',8081),MyServer)
s.serve_forever()
-----------------------------------------------------------------------
多线程
解决递归锁导致的死锁问题用:
lock=threading.RLock() #其他和lock用法一样
lock.acquire() #获取锁
lock.release() #释放锁
-----------------------
通过event对象控制线程执行顺序
event=threading.Event() #初始化
event.wait() #等待
event.set() #设置
event.clear() #清除阻塞
-----------------------
#t.setDaemon(True) 多线程守护线程和主线程一起退出用
#t.daemon=True 多进程守护进程和主进程一起退出用
-----------------------------------------------------------------------
#多线程队列用
import queue
#先进先出
q=queue.Queue(3)
#先进后出 q=queue.LifoQueue(3)
q.put(11) #放入
while 1:
q.get() #取出
#设置优先级
'''
q=queue.PriorityQueue(3)
q.put([1,'hello'])
q.put([2,'world'])
#越小越先出
q.qsize() 大小Queue(3)的值
q.empty() 是否为空
q.full() 是否满了
q.put_nowait('wo') 相当于q.put(block=False)
q.join() 队列为空时在执行别的操作
'''
------------------------------------------------------------------------
#多进程及通信
进程通信1:Queue
----------------
import multiprocessing,time
# 子进程要执行的代码
def run_proc(q):
time.sleep(0.2)
q.put(45667)
if __name__=='__main__':
print('start...')
q = multiprocessing.Queue() 进程通信1:Queue
p = multiprocessing.Process(target=run_proc, args=(q,))
p.start()
print(q.get())
p.join()
print('end')
管道消息传递2:Pipe
-------------------
from multiprocessing import Process,Pipe
# 子进程要执行的代码
def run_proc(conn):
print('parent:',conn.recv())
conn.send('hello parent !')
conn.close()
if __name__=='__main__':
print('start...')
parent_conn,child_conn = Pipe() #双向管道
p = Process(target=run_proc, args=(child_conn,))
p.start()
parent_conn.send('child hello!') #给子进程发消息
print('child:',parent_conn.recv()) #父接子进程消息
p.join()
print('end')
# 进程通信数据共享
------------------
from multiprocessing import Process,Manager
# 子进程要执行的代码
def run_proc(d,l):
d['name']='xiaoMing'
l.append(12)
if __name__=='__main__':
with Manager() as manager:
d=manager.dict() #创建字典
l=manager.list() #创建列表
p = Process(target=run_proc, args=(d,l))
p.start()
p.join()
print('dict:',d) #{'name': 'xiaoMing'}
print('list:',l) #[12]
-------------------------------------------------------------------
# 进程锁(操作同步资源用)
from multiprocessing import Process,Lock
# 子进程要执行的代码
def run_proc(l,i):
l.acquire()
print('进程锁 %s'%i)
l.release()
'''简写
with l:
print('进程锁 %s'%i)
'''
if __name__=='__main__':
lock=Lock()
for num in range(10):
Process(target=run_proc, args=(lock,num)).start()
-------------------------------------------------------------------
# 进程池
from multiprocessing import Process,Pool
# 子进程要执行的代码
def run_proc(i):
print('进程 %s'%i)
def Bar(args):
print('回调函数: %s'%args)
if __name__=='__main__':
pool=Pool(5) #进程数 不设置按默认cpu核数
for num in range(10):
pool.apply_async(func=run_proc, args=(num,),callback=Bar(num)) #(apply_async异步,apply同步)
pool.close()
pool.join() #close和join顺序固定
-----------------------------------------------------------------
# select 模块io并发
# 1.select
import socket
import select
s = socket.socket()
s.bind(('127.0.0.1',8888))
s.listen(5)
r_list = [s,]
num = 0
while True:
rl, wl, error = select.select(r_list,[],[],10)
num+=1
print('counts is %s'%num)
print("rl's length is %s"%len(rl))
for fd in rl:
if fd == s:
conn, addr = fd.accept()
r_list.append(conn)
msg = conn.recv(200)
conn.sendall(('first----%s'%conn.fileno()).encode())
else:
try:
msg = fd.recv(200)
fd.sendall('second'.encode())
except ConnectionAbortedError:
r_list.remove(fd)
s.close()
---------
# 2.epoll效果最好 window不支持 Linux,mac里用
import socket
import select
s = socket.socket()
s.bind(('127.0.0.1',8888))
s.listen(5)
epoll_obj = select.epoll()
epoll_obj.register(s,select.EPOLLIN)
connections = {}
while True:
events = epoll_obj.poll()
for fd, event in events:
print(fd,event)
if fd == s.fileno():
conn, addr = s.accept()
connections[conn.fileno()] = conn
epoll_obj.register(conn,select.EPOLLIN)
msg = conn.recv(200)
conn.sendall('ok'.encode())
else:
try:
fd_obj = connections[fd]
msg = fd_obj.recv(200)
fd_obj.sendall('ok'.encode())
except BrokenPipeError:
epoll_obj.unregister(fd)
connections[fd].close()
del connections[fd]
s.close()
epoll_obj.close()
------------------------------------------------------
# selectors 模块实现非阻塞式编程io并发(最好方案)
import selectors, socket
# 创建默认的selectors对象
sel = selectors.DefaultSelector()
# 负责监听“有数据可读”事件的函数
def read(skt, mask):
try:
# 读取数据
data = skt.recv(1024)
if data:
# 将读取的数据采用循环向每个socket发送一次
for s in socket_list:
s.send(data) # Hope it won't block
else:
# 如果该socket已被对方关闭,关闭该socket,
# 并从socket_list列表中删除
print('关闭', skt)
sel.unregister(skt)
skt.close()
socket_list.remove(skt)
# 如果捕捉到异常, 将该socket关闭,并从socket_list列表中删除
except:
print('关闭', skt)
sel.unregister(skt)
skt.close()
socket_list.remove(skt)
socket_list = []
# 负责监听“客户端连接进来”事件的函数
def accept(sock, mask):
conn, addr = sock.accept()
# 使用socket_list保存代表客户端的socket
socket_list.append(conn)
conn.setblocking(False)
# 使用sel为conn的EVENT_READ事件注册read监听函数
sel.register(conn, selectors.EVENT_READ, read) #②
sock = socket.socket()
sock.bind(('192.168.1.88', 30000))
sock.listen()
# 设置该socket是非阻塞的
sock.setblocking(False)
# 使用sel为sock的EVENT_READ事件注册accept监听函数
sel.register(sock, selectors.EVENT_READ, accept) #①
# 采用死循环不断提取sel的事件
while True:
events = sel.select()
for key, mask in events:
# key的data属性获取为该事件注册的监听函数
callback = key.data
# 调用监听函数, key的fileobj属性获取被监听的socket对象
callback(key.fileobj, mask)
------------------------------
# 异步并发模块 concurrent.futures
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, Executor
# ProcessPoolExecutor 进程
# 创建线程池:最大可用线程10
pool = ThreadPoolExecutor(10)
def run(val):
print(val)
# submit(fn, *args, **kwargs) fn:为需要异步执行的函数 args,kwargs:为给函数传递的参数
pool.submit(self.run, 666)
#obj=pool.map(task,range(10)) #批量创建进程/线程,取代了for+submit
pool.shutdown(wait=True)
#shutdown(wait=True) 关闭了池的入口,不允许在往里面添加任务了,会等带所有的任务执行完,结束阻塞(看情况使用)
#相当于进程池的pool.close()+pool.join()操作
wait=True,等待池内所有任务执行完毕回收完资源后才继续
wait=False,立即返回,并不会等待池内的任务执行完毕
但不管wait参数为何值,整个程序都会等到所有任务执行完毕
submit和map必须在shutdown之前
#可用with上下文管理替代shutdown(wait=True)
with ThreadPoolExecutor() as pool:
a=pool.submit(run, 666)
def back(v):
print(current_process().name,'拿到了结果',v.result())
a.add_done_callback(back)
# add_done_callback(parse) parse是一个回调函数
# 当任务执行结束拿到返回值的时候自动触发回调函数。并且把future当做参数直接传给回调函数parse
pool.result() #会造成死锁慎用 xx.result() xx可以指定别人等别人执行完在执行
# 这是在等待我执行任务得到的结果,如果一直没有结果,这里会导致我们所有任务编程了串行
-------------
运维自动化
---------
1. agent方式,模块:subprocess
import subprocess,re,requests
val=subprocess.getoutput('ipconfig')
ip=re.search(r'IPv4.*\:(.*?)子网',val,re.S)
if ip:
v=ip.group(1).strip()
da={'ip':v}
r=requests.post('http://127.0.0.1:8081/test',data=da)
if r.status_code==200:
print('data:',r.text)
else:
print('err=>',r)
else:
print('没有找到啊 !')
2. ssh方式 pip install paramiko
import paramiko
#创建ssh对象
ssh=paramiko.SSHClient()
#自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不再本地know_hosts文件中记录的主机将无法连接
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接SSH服务端,以用户名和密码进行认证
ssh.connect(hostname='192.168.1.105', port=22, username='root', password='123456')
# 打开一个Channel并执行命令
stdin, stdout, stderr = ssh.exec_command('df -h ') # stdout 为正确输出,stderr为错误输出,同时是有1个变量有值
# 打印执行结果
print(stdout.read().decode('utf-8'))
# 关闭SSHClient
ssh.close()