导入模块方式
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个百分号代表一个站位符
# !/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
# !/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()
#!/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没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入。
# !/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"))
#随机数 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)
# !/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
#!/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'))
# !/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可以
''' 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,贪婪匹配 贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配 正则 待匹配字符 匹配结果 说明 <.*>