py4常用模块

导入模块方式

import 单文件
from dir import file 目录下文件
如果有相同的名称,可以采用别名的方式
from dir import file as rename.file

pip3 requests install
源码下载后会出现STEUP.PY文件,然后PYTHON STEUP.PY INSTALL
注意依赖关系

__name__是什么鬼

# !/usr/bin/env python
# _*_coding:utf-8_*_
# Author:Joker


"""
my 注释
"""

# print(__doc__) # 获取文件注释

# print(__cached__)  # 字节码路径 pyc

# print(__file__) # 当前运行的py的路径,如果你跳到路径执行,就只显示文件名

import os
print(os.path.abspath(__file__)) # 永远的绝对路径

print(os.path.dirname(os.path.abspath(__file__)))  # 上一级目录

import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__))) # 上级目录添加到变量

import s2
print(s2.__package__) # 包位置
# /Users/liqianlong/Desktop/Django project/kkk/s6-python-develop/day21-模块&包&--file--&开发规范

print(__name__) # __main__  执行当前文件时,当前文件的特殊变量__name__ == '__main__'  

模块学习

#!/usr/bin/env python
#_*_coding:utf-8_*_

# os模块
# os模块是与操作系统交互的一个接口
'''
os.walk() 显示目录下所有文件和子目录以元祖的形式返回,第一个是目录,第二个是文件夹,第三个是文件
open(r'tmp\inner\file',w)    创建文件
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径  可以先记录当前文件目录
os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
os.curdir  返回当前目录: ('.')   没什么用
os.pardir  获取当前目录的父目录字符串名:('..')    没什么用
os.makedirs('dirname1/dirname2')    可生成多层递归目录 dirname1如果存在就在下面创建,不存在都创建,如果都存在就报错,可通过
                                    修改里面exist_ok=ok来解决这个报错
os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推,
                             但是若目录不为空,首先你要先删除文件,不然报错
os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()  删除一个文件
os.rename("oldname","newname")  重命名文件/目录
os.stat('path/filename')  获取文件/目录信息
os.sep    输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"
os.linesep    输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")  运行shell命令,直接显示
os.popen("bash command)  运行shell命令,获取执行结果
print(ret.read())   这样读取出来popen的结果
os.environ  获取系统环境变量

os.path 括号内pathn就是文件夹和文件
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path)返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)  如果path是绝对路径,返回True
os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
print(os.path.join(os.getcwd(),'filename'))
os.path.getatime(path)  返回path所指向的文件或者目录的最后访问时间
os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小
'''
# 注意:os.stat('path/filename')  获取文件/目录信息 的结构说明
'''
stat 结构:
st_mode: inode 保护模式
st_ino: inode 节点号。
st_dev: inode 驻留的设备。
st_nlink: inode 的链接数。
st_uid: 所有者的用户ID。
st_gid: 所有者的组ID。
st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
st_atime: 上次访问的时间。
st_mtime: 最后一次修改的时间。
st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。
'''



# sys模块
# sys模块是与python解释器交互的一个接口
'''
sys.argv           命令行参数List,第一个元素是程序本身路径            #做权限用
sys.exit(n)        退出程序,正常退出时exit(0)                         #常用
sys.version        获取Python解释程序的版本信息
sys.maxint         最大的Int值
sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform       返回操作系统平台名称
'''
# import sys
# # >python "2os&sys.py" egon somebody  #程序执行方式
# print(sys.argv)    #打印参数,0是"2os&sys.py"程序文件名字  1是egon 2是somebody
# name = sys.argv[1]
# password = sys.argv[2]
# if name == 'egon' and password == 'somebody':
#     print('继续执行程序')
# else:
#     sys.exit('登陆失败')

# 添加环境变量
# import sys
# sys.path.append('/root/dir/file')


# 进度条
import sys

import time

def view_bar(num,total):
    rate = float(num) / total
    rate_num = int(rate * 100)
    r = '\r%s>%d%%' % ('='*num,rate_num)
    # \r回到当前行的首部位
    sys.stdout.write(r) # 相对比print,就是没有换行符
    # sys.stdout.flush() # 输出清空


if __name__ == '__main__':
    print( '\r%s>%d%%' % ('=',1))
    print( '\r%s>%d%%' % ('=',2))
    print( '\r%s>%d%%' % ('=',98))
    print( '\r%s>%d%%' % ('=',100))
    for i in range(1,101):
        time.sleep(0.3)
        view_bar(i,100)

# %% 2个百分号代表一个站位符
os&sys

 

# !/usr/bin/env python
# _*_coding:utf-8_*_
# Author:Joker


import time

# print(time.time())   # 1531982635.617672 时间戳 1970年开始计数的

# print(time.ctime())  # Thu Jul 19 14:45:44 2018,当前时间

# print(time.ctime(time.time()-86400)) # Wed Jul 18 14:49:26 2018 时间戳转化为字符串时间

# print(time.gmtime())
# time.struct_time(tm_year=2018, tm_mon=7, tm_mday=19, tm_hour=6, tm_min=50, tm_sec=15, tm_wday=3, tm_yday=200, tm_isdst=0)
# time_obj = time.gmtime()
# print(time_obj.tm_year,time_obj.tm_mon) # 2018 7 注意下day的值,周一是0,而且是utc时间

# print(time.gmtime(time.time()-86400)) # 将时间戳转换成struct_time格式
# time.struct_time(tm_year=2018, tm_mon=7, tm_mday=18, tm_hour=6, tm_min=53, tm_sec=37, tm_wday=2, tm_yday=199, tm_isdst=0)

# print(time.localtime()) # 本地时间,按照服务器的时区
# time.struct_time(tm_year=2018, tm_mon=7, tm_mday=19, tm_hour=14, tm_min=56, tm_sec=14, tm_wday=3, tm_yday=200, tm_isdst=0)

# time_obj = time.gmtime()
# print(time.mktime(time_obj)) # 时间对象转成时间戳 # 1531954699.0

# tm = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()) # 将struct_time格式转化成指定的字符串格式
# print(tm) # 2018-07-19 15:02:11

# tm = time.strptime('2018-07-19','%Y-%m-%d') # 将字符串格式转化成struct_time格式
# print(tm)
# time.struct_time(tm_year=2018, tm_mon=7, tm_mday=19, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=200, tm_isdst=-1)




import datetime
# print(datetime.date.today()) # 2018-07-19,当前年月日

# print(datetime.date.fromtimestamp(time.time())) # 2018-07-19 将时间戳转换成日期格式

# print(datetime.datetime.now()) # 2018-07-19 15:10:00.874436 当前时间

# current_time = datetime.datetime.now()
# print(current_time.timetuple()) # 将字符串转换为struct_time格式
# time.struct_time(tm_year=2018, tm_mon=7, tm_mday=19, tm_hour=15, tm_min=11, tm_sec=30, tm_wday=3, tm_yday=200, tm_isdst=-1)

# str_to_date = datetime.datetime.strptime('09/10/12','%d/%m/%y')
# print(str_to_date) # 2012-10-09 00:00:00 将字符串转换成日期格式

# 时间加减
# current_time = datetime.datetime.now() # 当前时间
# print(datetime.datetime.now() + datetime.timedelta(days=10))
# 2018-07-29 15:15:42.874593 比现在+10天

# print(datetime.datetime.now() - datetime.timedelta(days=10))
# 2018-07-09 15:16:55.388891 比现在-10天

# print(datetime.datetime.now() - datetime.timedelta(hours=10))
# 2018-07-19 05:18:23.341908 比现在-10小时

# 时间替换
# current_time = datetime.datetime.now() # 当前时间
# print(current_time.replace(2200,2,2))
# 2200-02-02 15:20:34.209528

# 时间比较
# current_time = datetime.datetime.now() # 当前时间
# old_time = current_time.replace(2017,5)
# print(current_time > old_time) # True
time&datetime

 

# !/usr/bin/env python
# _*_coding:utf-8_*_
# Author:Joker



import shutil

# f1 = open('随便写的.txt',encoding='utf-8')
# f2 = open('lala','w',encoding='utf-8')

# shutil.copyfileobj(f1,f2) # 将文件内容拷贝到另一个文件中


# shutil.copyfile('随便写的.txt','haha') # 拷贝


# shutil.copymode('随便写的.txt','haha') # 仅拷贝权限,内容.组,用户可能是你拷贝时候的用户


# shutil.copystat('随便写的.txt','haha') # 拷贝状态信息


# shutil.copy('随便写的.txt','haha') # 拷贝文件和权限


# shutil.copy2('随便写的.txt','haha') # 拷贝文件和状态信息


# shutil.copytree('目录1','目录2') # 递归拷贝文件,目录名就可以


# shutil.rmtree('目录1') #删除目录,这里写当前目录名就可以


# shutil.move('file1','目录') # 目录名就可以


# shutil.make_archive(base_name=,format=)
# base_name 压缩包的文件名,也可以是压缩包的路径,如果只是文件名,则保存至当前目录,否则保存至指定路径
    # 如 WW,保存至当前目录
    # 如 /USER/WW 保存到/USER/目录

# format 压缩包种类,ZIP,TAR,BZTAR,GZTAR
# root_dir 要压缩的文件夹路径
# owner 用户,默认当前用户
# group 组,默认当前组
# logger 用于记录日志,通常是logging.Logger对象



# shutil.make_archive('shuti','zip','压缩文件的路径即可')




# ya
import zipfile
#
# z = zipfile.ZipFile('da.zip','w')
# z.write('lala')
# print('干点别的')
# z.write('haha')

# jie
z = zipfile.ZipFile('da.zip','w')
z.extractall()
z.close()


import tarfile

# 压缩
tar = tarfile.open('da.tar','w')
tar.add('绝对lujing', arcname='bbs2.zip')
tar.add('绝对lujing', arcname='cmdb.zip')
tar.close()

# 解压
tar = tarfile.open('your.tar','r')
tar.extractall()  # 可设置解压地址
tar.close()
shutil

 

#!/usr/bin/env python
#_*_coding:utf-8_*_

# 序列化模块
# 将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化
'''
比如,我们在python代码中计算的一个数据需要给另外一段程序使用,那我们怎么给?
现在我们能想到的方法就是存在文件里,然后另一个python程序再从文件里读出来。
但是我们都知道,对于文件来说是没有字典这个概念的,所以我们只能将数据转换成字典放到文件中。
你一定会问,将字典转换成一个字符串很简单,就是str(dic)就可以办到了,为什么我们还要学习序列化模块呢?
没错序列化的过程就是从dic 变成str(dic)的过程。现在你可以通过str(dic),将一个名为dic的字典转换成一个字符串,
但是你要怎么把一个字符串转换成字典呢?
聪明的你肯定想到了eval(),如果我们将一个字符串类型的字典str_dic传给eval,就会得到一个返回的字典类型了。
eval()函数十分强大,但是eval是做什么的?e官方demo解释为:将字符串str当成有效的表达式来求值并返回计算结果。
BUT!强大的函数有代价。安全性是其最大的缺点。
想象一下,如果我们从文件中读出的不是一个数据结构,而是一句"删除文件"类似的破坏性语句,那么后果实在不堪设设想。
而使用eval就要担这个风险。
所以,我们并不推荐用eval方法来进行反序列化操作(将str转换成python中的数据结构)
'''
# 序列化的目的
# 1、以某种存储形式使自定义对象持久化;
# 2、将对象从一个地方传递到另一个地方。
# 3、使程序更具维护性。
# 数据结构 --> 序列化 --> str
# str --> 反序列化 --> 数据结构

d = {'1':'v'}
print(str(d))
s = str(d)
print(eval(s),type(s))   #eval不安全,remove rm操作太危险

# json 不是python发明的,所有的语言都在用,语言之间用字符串传递
# json 字符串 字典 列表可以的
# json 模块提供四个功能:dumps,dump,loads,load

# 将PYTHON基本数据类型转化为字符串形式
import json
ret_s = json.dumps(d)
print(ret_s,type(ret_s))

# 将PYTHON字符串形式转化成基本数据类型
ret_d = json.loads(ret_s)
print(ret_d,type(ret_d))

import json
# li = "['alex','eric']" 报错,因为其他语言的原因,''在其他语言里面是字符
li = '["alex","eric"]'
ret = json.loads(li)
print(ret,type(ret)) # ['alex', 'eric'] 

#注意字符串必须是一个双引号,单引号就会报错
f = open('json_file')
d_s = f.read()
print(json.loads(d_s))
f.close()

# 小结   内存操作
#dumps  结构化的数据类型转字符串
#loads  字符串转结构化数据类型  结构化数据类型中的所有字符串必须是双引号引用

# 写回文件 dump load 操作文件跟序列化的关系
f = open('json_file','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f)     # 先序列化,在写文件
# f.write(json.dumps(dic))  #是先dumps转成字符串在写入文件
f.close()

f = open('json_file')
dic2 = json.load(f)  # 打开文件,然后转化成数据类型,load在你打开过程中帮你loads了
print(dic2,type(dic2)) #直接就是一个字典类型,不需要转化
f.close()




# pickle  所有数据类型都可以,但是只是Python自有的,而且是bytes(用于一种Python独特状态)
# json & pickle模块
# 用于序列化的两个模块
    # json,用于字符串 和 python数据类型间(列表,字典)进行转换
    # pickle,用于python特有的类型 和 python的数据类型间进行转换

# pickle模块提供了四个功能:dumps、dump(序列化,存)、loads(反序列化,读)、load  (不仅可以序列化字典,列表...可以把python中任意的数据类型序列化)
# python 特有的元祖  会被json搞成列表
# set               json不支持
tu = {1,2,3,4}
# import json
# print(json.dumps(tu))  #json不支持,所以这里不支持
import pickle
print(pickle.dumps(tu))    #bytes类型
pik_b = pickle.dumps(tu)
print(pickle.loads(pik_b)) #转回来
li = [1,2,3,4,5]
pickle.dump(li,open('db','rb'))

ret = pickle.load(open('db','rb'))
print(ret,type(ret))  # [1,2,3,4,5] list

# shelve模块
# shelve也是python提供给我们的序列化工具,比pickle用起来更简单一些。
# shelve只提供给我们一个open方法,是用key来访问的,使用起来和字典类似
import shelve
f = shelve.open('shelve_file')
f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'}  #直接对文件句柄操作,就可以存入数据
f.close()

import shelve
f1 = shelve.open('shelve_file')
existing = f1['key']  #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错
f1.close()
print(existing)

#注意:这个模块有个限制,它不支持多个应用同一时间往同一个DB进行写操作。
# 所以当我们知道我们的应用如果只进行读操作,我们可以让shelve通过只读方式打开DB
import shelve   #只读模式,就不会影响写的人了
f = shelve.open('shelve_file', flag='r')
existing = f['key']
f.close()
print(existing)

#注意:由于shelve在默认情况下是不会记录待持久化对象的任何修改的,
# 所以我们在shelve.open()时候需要修改默认参数,否则对象的修改不会保存。
import shelve
f1 = shelve.open('shelve_file')  #没有改
print(f1['key'])
f1['key']['new_value'] = 'this was not here before'
f1.close()

f2 = shelve.open('shelve_file', writeback=True)  #改了
print(f2['key'])
f2['key']['new_value'] = 'this was not here before'
f2.close()

# 小结:writeback方式有优点也有缺点。优点是减少了我们出错的概率,并且让对象的持久化对用户更加的透明了;
# 但这种方式并不是所有的情况下都需要,首先,使用writeback以后,shelf在open()的时候会增加额外的内存消耗,
# 并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间。
# 因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入。
json&shelve

 

# !/usr/bin/env python
# _*_coding:utf-8_*_
# Author:Joker


import configparser

# 生成配置文件
# config = configparser.ConfigParser()
#
# config["DEFAULT"] = {'ServerAliveInterval': '45',
#                      'Compression': 'yes',
#                      'CompressionLevel': '9'}
#
# config['bitbucket.org'] = {}
# config['bitbucket.org']['User'] = 'hg'
# config['topsecret.server.com'] = {}
# topsecret = config['topsecret.server.com']
# topsecret['Host Port'] = '50022'  # mutates the parser
# topsecret['ForwardX11'] = 'no'  # same here
# config['DEFAULT']['ForwardX11'] = 'yes'
# with open('example.ini', 'w') as configfile:
#     config.write(configfile)



# 读取配置文件
conf = configparser.ConfigParser()
conf.read('example.ini')


print(conf.sections()) # 不会打印DEFAULT,打印节点
print(conf.defaults()) # OrderedDict([('compression', 'yes'), ('serveraliveinterval', '45'), ('compressionlevel', '9'), ('forwardx11', 'yes')])


print(conf['bitbucket.org']['user'])


# 增删改查
# secs = config.sections()
# print secs
# options = config.options('group2')
# print options

# item_list = config.items('group2')
# print item_list

# val = config.get('group1','key')
# val = config.getint('group1','key')

# ########## 改写 ##########
# sec = config.remove_section('group1')
# config.write(open('i.cfg', "w"))

# sec = config.has_section('wupeiqi')
# sec = config.add_section('wupeiqi')
# config.write(open('i.cfg', "w"))


# config.set('group2','k1',11111)
# config.write(open('i.cfg', "w"))

# config.remove_option('group2','age')
# config.write(open('i.cfg', "w"))
configparser

 

#随机数
import random
#1.随机小数
print(random.random())  #从0-1之间的小数
print(random.uniform(1,3)) #1-3之间的小数

#2.随机整数
l = []
l.append(str(random.randint(0,9)))  #0-9之间的随机数
l.append(str(random.randint(0,9)))
print(''.join(l))   #显示97
print(l)            #['9', '7']
print(random.randrange(1,4,2))  #也可以用布长来做,这是打印1-4之间的奇数1 3

#3.随机一个返回
print(random.choice([1,2,'b',4,'a',6])) #随机选择一个返回,[]()都可以

#4.随机多个返回,返回的个数为函数的第二个参数,本例中是返回3个
print(random.sample([1,2,'b',4,'a',6],3)) #返回3个,和之前的  返回的是列表

#5.打乱顺序
l = list(range(100))
print(l)   #正常顺序
random.shuffle(l)
print(l)   #顺序打乱

#写一个验证码
#首先要有数字,其次要有字母,一共4位,可以重复
#65-91是a-z,用chr()可以转成字母
#print(chr(90))
#普通版本
new_num_l = list(map(str,range(10)))  #['0','1'...'9']  #用来存数字
alph_l = [chr(i) for i in range(65,91)]  #列表推导式   用来存字母
new_num_l.extend(alph_l)  #包含字母和数字
ret_l = [random.choice(new_num_l) for i in range(4)] #取得重复随机 列表推导式
print(''.join(ret_l))       #因为是列表,所以join一下
ret = random.sample(new_num_l,4)  #取得不重复随机
print(''.join(ret))

# 写成函数
def myrandom():
    new_num_l = list(map(str,range(10)))
    alph_l = [chr(i) for i in range(97,123)]  #列表推导式
    new_num_l.extend(alph_l)
    ret_l = [random.choice(new_num_l) for i in range(4)]  #列表推导式
    return ''.join(ret_l)
print(myrandom())

# def suiji(num):
#     return [random.choice(list(map(str,range(10))).extend([chr(i) for i in range(97,123)])) for j in range(num)]
# x = suiji(4)
# print(x)
random

 

# !/usr/bin/env python
# _*_coding:utf-8_*_
# Author:Joker




# 用于加密相关操作

import hashlib


obj = hashlib.md5()

obj.update(bytes('joker',encoding='utf-8'))

ret = obj.hexdigest()

print(ret)  #  9facbf452def2d7efc5b5c48cdb837fa



# 加盐操作,自己的KEY

obj = hashlib.md5(bytes('happy',encoding='utf-8'))

obj.update(bytes('joker',encoding='utf-8'))

ret = obj.hexdigest()

print(ret)  #  c17ebd08acae8d7a822cec70da3fcf99
hashlib

 

#!/usr/bin/python env
#_*_coding:utf-8_*_

#collections模块的用法
'''
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
1.namedtuple: 生成可以使用名字来访问元素内容的tuple
2.deque: 双端队列,可以快速的从另外一侧追加和推出对象
3.Counter: 计数器,主要用来计数
4.OrderedDict: 有序字典
5.defaultdict: 带有默认值的字典
'''

# 1.namedtuple (重点)
from collections import namedtuple
Ponit = namedtuple('Ponit',['x','y','z'])
p = Ponit(1,2,5)
print(p.x)
print(p.y)
print(p.z)

# 2.deque
'''
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
'''
from collections import deque
q = deque(['a', 'b', 'c'])
q.append('x')
q.appendleft('y')
# print(q)
#deque(['y', 'a', 'b', 'c', 'x'])
# deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素

# 3.OrderedDict (重点)消耗内存
'''
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict:
'''
from collections import OrderedDict
d = dict([('a', 1), ('b', 2), ('c', 3)])
print(d)
#d dict的Key是无序的
#{'a': 1, 'c': 3, 'b': 2}
od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
print(od)
#od OrderedDict的Key是有序的
#OrderedDict([('a', 1), ('b', 2), ('c', 3)])

# 注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序
od = OrderedDict()
od['z'] = 1
od['y'] = 2
od['x'] = 3
od.keys() # 按照插入的Key的顺序返回
#['z', 'y', 'x']

# 4.defaultdict (重点)(带默认的字典,就是当这个)
# 有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。
# 普通代码,需要判断这个key,vales存在不存在
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = {}
for value in  values:
    if value>66:
        if my_dict.get('k1'):
            my_dict['k1'].append(value)
        else:
            my_dict['k1'] = [value]
    else:
        if my_dict.get('k2'):
            my_dict['k2'].append(value)
        else:
            my_dict['k2'] = [value]

# 使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:
# 进阶版本   会给返回默认的参数,用了匿名函数的原理
from collections import defaultdict
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = defaultdict(list)
for value in  values:
    if value>66:
        my_dict['k1'].append(value)
    else:
        my_dict['k2'].append(value)
print(my_dict['k1'])

#匿名函数
from collections import defaultdict
def func():
    return 'N/A'
my_dict = defaultdict(func)
print(my_dict['k'])

# 5.Counter
# Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,
# 其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。
from collections import Counter
c = Counter('abcdeabcdabcaba')
print(c)
# 输出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
# http://www.cnblogs.com/Eva-J/articles/7291842.html
print('aaab'.count('a'))
collections

 

# !/usr/bin/env python
# _*_coding:utf-8_*_
# Author:Joker



#!/usr/bin/env python
#_*_coding:utf-8_*_

#linux 上调用python脚本
#os.system输出命令结果到屏幕,返回命令执行状态
#os.popen("dir") 返回内存对象,需要单独去取一下
#os.popen("dir").read() 保存命令的执行结果输出,但是不返回执行状态
#

#py 2.7  from only linxu 2.7....
#commands   = = == =  commands.getstatusoutput("dir") 返回执行状态和结果
#print(res[0])   (res[1])


#subprocess  python 3.5 ___run
import subprocess
# subprocess.run(["df","-h"])
# subprocess.run(["df","-h","|","grep","sda1"]) 命令执行会报错,因为加上管道符他解决不了
# subprocess.run(["df -h | grep sda1",shell=True]) 不需要python解析这个字符串,传给linux自己去解析

#os.system  = = = subprocess.call("df -h",shell=True)输出命令结果到屏幕,返回命令执行状态
#subprocess.checkcall("df -h",shell=True)如果报错就抛出异常,也是返回状态
#subprocess.getstatusoutput("df -h",shell=True)返回执行状态和结果  ==== commands.getstatusoutput("dir")
#subprocess.getoutput("df -h",shell=True)返回结果= = =os.popen("dir")
#

#subprocess.Popen("ifconfig|grep 192",shell=True,subprocess.PIPE)  pipe 管道意思
#res.stdout.read()  标准输出
#subprocess.Popen("dddd",shell=True,subprocess.PIPE,stderr=subprocess.PIPE)
#res.stderr.read()  标准错误
#subprocess.Popen("sleep30:echo 'hello'",shell=True,subprocess.PIPE,stderr=subprocess.PIPE)
#print(res.poll())  这个是返回执行的状态,执行完了返回0没有执行返回None
#print(res.wait())  等待返回结果

#terminate()杀掉所启动的进程
#subprocess.Popen("sleep30:echo 'hello'",shell=True,subprocess.PIPE,stderr=subprocess.PIPE)
#res.terminate()
#res.stdout.read()  是没有结果的,因为在上一个命令进程杀掉了

#communicate()等待任务结束  忘了他吧
#subprocess.Popen(['python3'],shell=True,subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)
#res.stdin.write(b"print(1)")
#res.stdin.write(b"print(2)")
#res.communicate()

#cwd新启动的shell环境默认在哪个地方
#subprocess.Popen(['pwd'],shell=True,subprocess.PIPE,cwd="/tmp")
#res.stdout.read()

#subprocess 交互输入密码
#subprocess.Popen("sudo apt-get install vim",shell=True) 环境乱了
#echo "pwd" | sudo -S apt-get install vim    -S从标准输入读取密码
#subprocess.Popen("echo 'pwd' | sudo -S apt-get install vim ",shell=True) 通过python可以
subprocess

 

'''
1.字符组:[0-9][a-z][A-Z]
在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示
字符分为很多类,比如数字、字母、标点等等。
假如你现在要求一个位置"只能出现一个数字",那么这个位置上的字符只能是0、1、2...9这10个数之一。
可以写成这种 [0-5a-eA-Z]  取范围的匹配

2.字符
.   匹配除换行符以外的任意字符
\w  匹配字母或数字或下划线
\s  匹配任意的空白符
\d  匹配数字
\n  匹配一个换行符
\t  匹配一个制表符
\b  匹配一个单词的结尾
^   匹配字符串的开始
$   匹配字符串的结尾
\W  匹配非字母或数字或下划线
\D  匹配非数字
\S  匹配非空白符
a|b 匹配字符a或字符b
()  匹配括号内的表达式,也表示一个组
[...]   匹配字符组中的字符
[^...]  匹配除了字符组中字符的所有字符

3.量词
量词  用法说明
*   重复零次或更多次
+   重复一次或更多次
?   重复零次或一次
{n} 重复n次
{n,}    重复n次或更多次
{n,m}   重复n到m次

4. .^$
正则  待匹配字符   匹配结果     说明
海. 海燕海娇海东   海燕海娇海东 匹配所有"海."的字符
^海. 海燕海娇海东  海燕        只从开头匹配"海."
海.$ 海燕海娇海东  海东        只匹配结尾的"海.$"

5.*+?{}
正则      待匹配字符                   匹配结果                说明
李.?     李杰和李莲英和李二棍子     李杰/李莲/李二            ?表示重复零次或一次,即只匹配"李"后面一个任意字符 
李.*     李杰和李莲英和李二棍子     李杰和李莲英和李二棍子    *表示重复零次或多次,即匹配"李"后面0或多个任意字符
李.+     李杰和李莲英和李二棍子     李杰和李莲英和李二棍子    +表示重复一次或多次,即只匹配"李"后面1个或多个任意字符
李.{1,2} 李杰和李莲英和李二棍子     李杰和/李莲英/李二棍        {1,2}匹配1到2次任意字符

注意:前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配
正则      待匹配字符                   匹配结果        说明
李.*?     李杰和李莲英和李二棍子       李/李/李         惰性匹配

6.字符集[][^]
正则                   待匹配字符                  匹配结果                说明
李[杰莲英二棍子]*      李杰和李莲英和李二棍子     李杰/李莲英/李二棍子     表示匹配"李"字后面[杰莲英二棍子]的字符任意次 
李[^和]*               李杰和李莲英和李二棍子     李杰/李莲英/李二棍子     表示匹配一个不是"和"的字符任意次
[\d]                   456bdha3                   4/5/6/3                  表示匹配任意一个数字,匹配到4个结果
[\d]+                  456bdha3                   456/3                    表示匹配任意个数字,匹配到2个结果

7.分组()或|和[^]
身份证号码是一个长度为15或18个字符的字符串,如果是15位则全部?️数字组成,首位不能为0;如果是18位,则前17位全部是数字,末位可能是数字或x,下面我们尝试用正则来表示:
正则                                待匹配字符                  匹配结果                说明
^[1-9]\d{13,16}[0-9x]$              110101198001017032          110101198001017032      表示可以匹配一个正确的身份证号
^[1-9]\d{13,16}[0-9x]$              1101011980010170            1101011980010170        表示也可以匹配这串数字,但这并不是一个正确的身份证号码,它是一个16位的数字
^[1-9]\d{14}(\d{2}[0-9x])?$         1101011980010170            False                   现在不会匹配错误的身份证号了()表示分组,将\d{2}[0-9x]分成一组,就可以整体约束他们出现的次数为0-1次
^([1-9]\d{16}[0-9x]|[1-9]\d{14})$   110105199812067023          110105199812067023      表示先匹配[1-9]\d{16}[0-9x]如果没有匹配上就匹配[1-9]\d{14}

8.转义符\
在正则表达式中,有很多有特殊意义的是元字符,比如\d和\s等,如果要在正则中匹配正常的"\d"而不是"数字"就需要对"\"进行转义,变成'\\'。
在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次"\d",字符串中要写成'\\d',那么正则里就要写成"\\\\d",这样就太麻烦了。这个时候我们就用到了r'\d'这个概念,此时的正则是r'\\d'就可以了。
正则                   待匹配字符                  匹配结果                说明
d                      \d                         False                   因为在正则表达式中\是有特殊意义的字符,所以要匹配\d本身,用表达式\d无法匹配
\\d                    \d                          True                    转义\之后变成\\,即可匹配
"\\\\d"                '\\d'                       True                    如果在python中,字符串中的'\'也需要转义,所以每一个字符串'\'又需要转义一次
r'\\d'                  r'\d'                     True                    在字符串之前加r,让整个字符串不转义

9,贪婪匹配
贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配
正则                   待匹配字符                  匹配结果                说明
<.*>                   
                    
                    

你可能感兴趣的:(shell,json,运维)