1.集合的概念html
集合是一个无序的,不重复的数据组合,它的主要做用以下python
*去重,把一个列表变成集合,就自动去重了linux
*关系测试,测试两组数据以前的交集、并集、差集、子集、父级、对称差集,判断没有交集等关系git
2.经常使用操做:程序员
1):集合的增删改查:算法
1 #http://www.cnblogs.com/Jame-mei 2 #集合的增删改查等基本操做 3 4 list1=set([1,3,5,7]) 5 6 #1.增长 7 list1.add(9) #添加单项,update添加多项。 8 list1.add('a') 9 print (list1): 10 {1, 3, 5, 7, 9,'a'} 11 12 ======================================= 13 #2.删除 14 list1.remove(1) #删除指定单个,若是指定不存在报错 15 list1.pop() #删除任意并返回 16 list1.discard('absdf') ##删除指定单个,若是指定不存在返回None值(不报错) 17 18 print (list1): 19 {3, 5, 7} 20 ======================================= 21 22 #3.修改 23 list1.update([2,4,6]) #注意这里格式,为列表的格式!! 24 list1.update(['a','A','b','C']) 25 print (list1)#(输出后,会添加到集合里,顺序是随机的!) 26 {1, 2, 3, 4, 5, 6, 7, 'b', 'C', 'a', 'A'} 27 28 29 list2=set('123') #注意这里的类型为字符串类型! 30 list2.update('456') 31 list3.update(('123','789')) 32 print (list2) 33 print (list2)#(输出后,会添加到即合理里,顺序是随机的!) 34 {'6', '2', '4', '5', '1', '3','123','456','789'} 35 36 37 38 list3=set((1,2,3,4)) #注意这里的类型为元祖! 39 list3.update((456,)) #添加单个元祖的时候,必需要加,逗号,否则会报错。 40 print (list3) # 41 {1, 2, 3, 4, 456} 42 43 44 list4=set({'name':'小明','sex':'男'}) #添加字典到集合中 45 list4.update({'age':25,'address':'abc'}) 46 47 print (list4)#输出后,只有key 48 {'sex', 'name', 'address', 'age'} 49 50 51 ======================================== 52 53 #4.查看 54 55 #1):长度 56 print(len(list1)) 57 58 #2):查看元素是否在集合中(列表,字典,集合,字符串均可以用in 或者not in来判断!!!) 59 print (5 in list1) 60 #3):查看元素是否不是list1中 61 print (9 not in list1) 62 63 #4):测试list1是不是list2的子集 64 list2=set([1,3,5,7,9]) 65 66 67 print(list1.issubset(list2)) 68 #运算符 69 print (list1<=list2) 70 71 #5):测试list2是不是list1的父级 72 print(list2.issuperset(list1)) 73 #运算符 74 print (list2>=list1) 75 76 #还有并集 | ,差集 - ,对称差集 ^,浅coyp: list1.copy等等
2):常见的集合运算和集合运算符shell
1 #Author Jame-Mei 2 3 #1.去除除列表中重复值 4 list1=[1,3,5,7,1,2,4,7] 5 6 list1=set(list1) 7 print (list1,type(list1)) 8 9 output: 10 {1, 2, 3, 4, 5, 7} <class 'set'> 11 =========================================================================================>>>>>>>> 12 13 14 #2.取交集:关系测试 15 list1=set([1,3,6,7,9]) 16 list2=set([2,4,6,7,8]) 17 #其中重复为6,7 18 print (list1,list2): 19 {1, 3, 6, 7, 9} {2, 4, 6, 7, 8} 20 21 #list3为交集的元素 22 list3=list1.intersection(list2) 23 print (list3): 24 {6, 7} 25 26 #交集元算符:& (两边无前后顺序) 27 list1 & list2 28 =========================================================================================>>>>>>>> 29 30 31 #2.取并:union() 32 list1=set([1,3,5]) 33 list2=set([2,4,6]) 34 35 list3=list1.union(list2) 36 print (list3): 37 {1, 2, 3, 4, 5, 6} 38 39 #并集运算符:| (两边无前后顺序) 40 list1 | list2 41 =========================================================================================>>>>>>>> 42 43 44 #3.差集:求list1和list2共有的之外的,各自的元素。 45 list1=set([1,3,5,7,9]) 46 list2=set([2,4,6,7,9]) 47 48 #取list1的差集,list2中没有的,属于list1的。 49 list3=list1.difference(list2) 50 print (list3): 51 {1, 3, 5} 52 53 #取list2的差集,list1中没有的,属于list2的。 54 list4=list2.difference(list1) 55 print (list4): 56 {2, 4, 6} 57 58 #差集运算符: - (在左边,不在右边) 59 list1 - list2 60 61 list2 - list1(差集的元素在list2中,不在list1中) 62 =========================================================================================>>>>>>>> 63 64 65 #4.子集:list1是不是list2的子集(儿子),list1里面有的list2都有,list2里面有的,list1不必定有(list2包括list1) 66 list1=set([1,3,5]) 67 list2=set([1,3,5,7,9]) 68 print (list1.issubset(list2)): 69 True 70 =========================================================================================>>>>>>>> 71 72 73 74 #5.父级:list1是不是list2的父级(父亲),list1包括list2,list1里面有的list不必定有,list2有的list1必定有。 75 list2=set([1,3,5]) 76 list1=set([1,3,5,7,9]) 77 print(list1.issuperset(list2)): 78 True 79 =========================================================================================>>>>>>>> 80 81 82 #6.对称差集:去除2者重复后的全部元素,或者这二者的差集相加,(互相都没有的和)就是对称差集。 83 list2=set([1,3,5,8,10,12]) 84 list1=set([1,3,5,7,9]) 85 86 print (list1.symmetric_difference(list2)): 87 {7, 8, 9, 10, 12} 88 89 #对称差集的元算符: ^ (返回一个新的 set 包含 list1 和 list2 中不重复的元素 ,无顺序关系!) 90 list1 ^ list2 91 92 =========================================================================================>>>>>>>> 93 #7.判断没有交集,True=没有交集,False=有交集。 94 list1=set([1,3,5]) 95 list2=set([2,4,6]) 96 97 flag=list1.isdisjoint(list2) 98 print(flag): 99 True
*对文件操做流程:编程
1):打开文件,获得文件句柄并赋值给一个变量windows
2):经过句柄对文件进行操做python3.x
3):关闭文件
*打开文件的模式有:
"+" 表示能够同时读写某个文件:
"U"表示在读取时,能够将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)
"b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)
1.文件的基本操做
1 #Author:Jame Mei 2 #在当前目录新建yesterdaytext和yesterday两个文件 3 4 '''#1.默认方式为'r'的方式打开读取文件 5 file1=open("yesterdaytext",encoding='UTF-8').read() 6 print (file1) 7 ''' 8 9 10 """ 11 #2.读取改进款,f为文件句柄(记录文件的文件名、文件位置,文件大小等等),'r'打开文件的模式:注意位置,不写默认r模式。 12 f=open('yesterdaytext','r',encoding='utf-8') 13 data1=f.read() 14 data2=f.read() 15 print (data1) #data1正常输出!! 16 print ("=========data2=====发现data2为空....没法再从头读一遍!===") 17 print (data2) 18 """ 19 20 '''#3.写覆盖模式w 21 f=open("yesterday",'w',encoding='utf-8') 22 f.write("我爱北京天安门\n") 23 f.write("天安门上红旗飘扬") 24 ''' 25 26 '''#4.写追加模式a 27 f=open("yesterday",'a',encoding='utf-8') 28 29 f.write("one night beijin,我留下不少情!") 30 f.write('\n不敢在午夜问路,怕惊醒了帝都的魂!') 31 '''
2.文件操做的一些方法
1 #Author http://www.cnblogs.com/Jame-mei 2 3 '''#1.读文件的前五行 4 f=open('yesterdaytext','r',encoding='utf-8') 5 6 方法1:(计数法) 7 count=0 8 for line in f: 9 if count<5: 10 print (line.strip()) 11 else: 12 break 13 count+=1 14 15 方法2:(最简法) 16 for i in range(5): 17 print (f.readline().strip()) 18 19 方法3:(取小标法) 20 for index,line in enumerate(f.readlines()): 21 if index<5: 22 print (line.strip()) 23 else: 24 break 25 ''' 26 27 28 '''#2.读取文件,跳过第十行显示分割线(打印出来发现第十行被print覆盖了,源文件没改变)! 29 f=open('yesterdaytext','r',encoding='utf-8') 30 方法1:(下标法) 31 for index,line in enumerate(f.readlines()): 32 if index==9: 33 print ('-------------------------------------我是分割线------------------------------') 34 continue 35 print (line.strip()) 36 37 38 方法2:计数法: 39 count=0 40 for line in f: 41 if count==9: 42 print ('----------------------第10行分割线--------------------') 43 else: 44 print (line.strip()) 45 count+=1 46 47 ''' 48 49 '''#3.readline只适合读取小文件,用下面的方式来读,效率高,内存中只保存一行,适合数据了大的场景!! 50 #f至关于迭代器 51 count=0 52 f=open('yesterdaytext','r',encoding='utf-8') 53 for line in f: 54 if count==9: 55 print ('---------------------------过滤第10行-------------------------->>>>>>>>>>>>>>') 56 count += 1 57 continue 58 print (line.strip()) 59 count+=1 60 ''' 61 62 '''#4.对于read()读过一遍后,没法再从头读,进行解答。 63 #重要函数readline(),seek()! 64 上文疑问实例预览: 65 data1=f.read() 66 data2=f.read() 67 print (data1) #data1正常输出!! 68 print ("=========data2=====发现data2为空....没法再从头读一遍!===") 69 print (data2) 70 71 #解决: 72 f=open('yesterdaytext','r',encoding='utf-8') 73 print (f.tell()) #告诉目前光标的位置! 74 print (f.readline()) #读取一行 75 print (f.readline()) #读取2行后,我如今想返回? 76 #print (f.read(5)) #去读指定的个数字符 77 print (f.tell()) 78 79 f.seek(0)#返回开头的光标的位置! 80 #f.seek(10) #把光标移动到第10个字符前,readline()从第10个字符读到第一行的结尾。 81 print (f.readline()) 82 print (f.tell()) #又到了读完第一行的光标位置! 83 ''' 84 85 '''#5.enconding()方法,fileno()方法读取文件的内存里的编号,isatty()判断是否一个底层不可打印设备。 86 f=open('yesterdaytext','r',encoding='utf-8') 87 print(f.encoding): 88 utf-8 89 print (f.fileno()): 90 3 91 print (f.isatty()): 92 False 93 ''' 94 95 '''#6.seekable ,判断是否能够移动。readable(),writeable() 96 f=open('yesterdaytext','r',encoding='utf-8') 97 98 print (f.seekable()): 99 True 100 print (f.readable()): 101 True 102 print (f.writable()): 103 False 104 ''' 105 106 '''#7.flush(),在windows或者linux的终端窗口下效果比较明显,防止断电没有从内存中写入到磁盘。 107 #closed判断文件是否关闭了,没有关闭False! 108 f=open('yesterday02','w',encoding='utf-8') 109 f.write("hello") #在dos下写过以后,查看yesterday02并无写入,flush()以后才能看到存储到文件中。 110 f.flush() 111 112 print (f.closed): 113 False 114 ''' 115 116 '''#8.truncate()截断,w若是不写会清空文件,a若是不写默认不操做。写了10,从第10个字符截断,后面的删除。 117 f=open('yesterday02','a',encoding='utf-8') 118 #f.truncate() 119 f.seek(10) #光标跳到第10个字符,截图前20个,后面的删除!! 120 f.truncate(20) 121 '''
实现windows or linux安装进度条打印效果:
1 #Author:Jame Mei 2 import sys,time 3 4 #实现windows安装进度条显示.......... 5 for i in range(30): 6 sys.stdout.write("#") 7 sys.stdout.flush() 8 time.sleep(0.3)
3.文件操做的重要参数操做:
r+、w+、a+、rb、wb等
1 #Author: http://www.cnblogs.com/Jame-mei 2 '''#1.open()的r+(读写)参数实例,打开读并追加这个比较经常使用!! 3 f=open('yesterdaytext','r+',encoding='utf-8') 4 count=0 5 for lin in f: 6 if count==3: 7 f.write("\n>>>>>打印前三行,开始w的操做>>>") #发现不管如何都没法在第三行以后写,只能从最后开始追加写入!! 8 count+=1 9 10 print(f.readline()) 11 count+=1 12 ''' 13 14 15 '''#2.open()的w+(写读)参数实例,依然和r+同样,只能从文件的末尾追加写入!这个应用场景比较少 16 f=open('yesterday02','w+',encoding='utf-8') 17 f.write("123456789\n") 18 f.write("23456789\n") 19 f.write("3456789\n") 20 21 print(f.tell()) 22 f.seek(10) 23 print (f.tell()) 24 25 print (f.readline()) 26 27 f.write("456789") 28 f.close() 29 ''' 30 31 32 33 '''#3.open()的a+ 追加读写,a不能读其余和a+同样 34 f=open('yesterdaytext','a+',encoding='utf-8') 35 f.seek(0) #若是不移动到文件开头,读出来的为空白! 36 37 print(f.readline()) 38 39 f.write('a+++++++光标移动到开始了,依然会追加到末尾!') 40 #a+存在则光标移动到最后,不存在则建立。 41 ''' 42 43 44 #4.open()的rb,wb:以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。通常用于非文本文件如图片等。 45 '''f=open('yesterdaytext','rb') #能够以2进制的方式读出来,不进行解码decode()的话,会带b''的方式显示。 46 print (f.readline()) 47 print (f.readline().decode()) #解码成utf-8格式显示 48 #若是不去掉enconfing='utf-8'则会valueError: binary mode doesn't take an encoding argument 49 50 51 #rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。通常用于非文本文件如图片等。 52 f=open('yesterday02','rb+') 53 print (f.readline()) 54 f.write("2222".encode()) #会在第二行写入,在这行甚至后面行会被覆盖! 55 print (f.readline()) 56 f.write("111111111111111".encode()) 57 58 59 60 #wb以二进制格式打开一个文件只用于写入。若是该文件已存在则将其覆盖。若是该文件不存在,建立新文件。通常用于非文本文件如图片等。 61 f=open('yesterday02','wb') #二进制写模式,要把字符串转换bytes 62 f.write("cedfg".encode()) #encode默认utf-8 63 #字符串若是不转换成bytes,则出现:TypeError: a bytes-like object is required, not 'str' 64 65 66 #wb+以二进制格式打开一个文件用于读写。若是该文件已存在则将其覆盖。若是该文件不存在,建立新文件。通常用于非文本文件如图片等。 67 f=open('yesterday02','wb+') 68 print (f.readline().decode()) 69 f.write('2222222222222222'.encode()) 70 '''
4.with语句
为了不打开文件后忘记关闭,能够经过管理上下文,即:
1
2
3
|
with
open
(
'log'
,
'r'
) as f:
...
|
如此方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。
在Python 2.7 后,with又支持同时对多个文件的上下文进行管理,即:
1
2
|
with
open
(
'log1'
) as obj1,
open
(
'log2'
) as obj2:
pass
|
Python官方建议若是一行不要超过80个字符,因此建议同时打开过个文件的时候这样写比较规范,并且方便观看:
1.修改文件中的内容:
思路1:找到须要修改的地方后,修改后另存到新的文件中。
思路2:须要打开2个文件,一个文件读r,一个文件负责写w。
1 f_old=open('yesterdaytext','r',encoding='utf-8') 2 f_new=open('yesterdaytext.bak','w',encoding='utf-8') 3 ''' 4 for line in f_old: 5 if '肆意的快乐等我享受' in line: 6 line=line.replace('肆意的快乐等我享受','肆意的快乐等Jame享受') 7 8 f_new.write(line) #省略if下面和else下面都写这句,反正都须要执行的操做。 9 10 11 f_old.close() 12 f_new.close()
2.做业程序练习
程序1: 实现简单的shell sed替换功能
1 #Author Jame-Mei 2 import sys 3 4 f_old=open('oldfile','r',encoding='utf-8') 5 f_new=open('oldfile.bak','w',encoding='utf-8') 6 7 find_str=sys.argv[1] #向脚本里传须要查找字符串-参数1 8 replace_str=sys.argv[2] #向脚本传替换的字符串-参数2 9 10 for line in f_old: 11 if find_str in line: 12 line=line.replace(find_str,replace_str) 13 14 f_new.write(line) #去除else,更加简洁 15 16 f_old.close() 17 f_new.close()
程序2:修改haproxy配置文件
需求以下:
1 需求: 2 一、查 3 输入:www.oldboy.org 4 获取当前backend下的全部记录 5 6 二、新建 7 输入: 8 arg = { 9 'bakend': 'www.oldboy.org', 10 'record':{ 11 'server': '100.1.7.9', 12 'weight': 20, 13 'maxconn': 30 14 } 15 } 16 17 三、删除 18 输入: 19 arg = { 20 'bakend': 'www.oldboy.org', 21 'record':{ 22 'server': '100.1.7.9', 23 'weight': 20, 24 'maxconn': 30 25 } 26 } 27 28 29 原配置文件: 30 global 31 log 127.0.0.1 local2 32 daemon 33 maxconn 256 34 log 127.0.0.1 local2 info 35 defaults 36 log global 37 mode http 38 timeout connect 5000ms 39 timeout client 50000ms 40 timeout server 50000ms 41 option dontlognull 42 43 listen stats :8888 44 stats enable 45 stats uri /admin 46 stats auth admin:1234 47 48 frontend oldboy.org 49 bind 0.0.0.0:80 50 option httplog 51 option httpclose 52 option forwardfor 53 log global 54 acl www hdr_reg(host) -i www.oldboy.org 55 use_backend www.oldboy.org if www 56 57 backend www.oldboy.org 58 server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000
实现过程:
1):流程思惟导图
2):代码
1 # Author: www.cnblogs.com/Jame-mei 2 3 4 import os,sys 5 6 7 def numif(number_input): # 判断输入是否为数字 8 while not number_input.isdigit(): # 输入不是数字就进入循环 9 number_input = input('\033[31m 输入%s不是数字,请从新输入!\033[0m' % number_input) # 提示从新输入 10 number = number_input 11 return number 12 13 14 def show_list(file): # 查询显示并将文本生成程序须要的字典和列表 15 backend_list = [] 16 backend_all_dict = {} 17 backend_dict = {} 18 server_list = [] 19 with open(file,'r') as f: # 读取haproxy文件 20 for line in f: 21 22 line = line.strip() 23 if line.startswith('backend') == True: # 判断是不是backend开头,读取backend信息写到backend_list中 24 backend_name = line.split()[1] 25 backend_list.append(backend_name) # 将文件中backend加到列表中 26 server_list = [] # 清空server_list里的记录,遇到新backend能够输入新的server_list 27 28 elif line.startswith('server') == True: # 判断是不是server开头,读取server信息写到backend_all_dict中 29 backend_dict['name'] = line.split()[1] # 读取文件中server的name 30 backend_dict['IP'] = line.split()[2] # 读取文件中server的IP 31 backend_dict['weight'] = line.split()[4] # 读取文件中server的weight 32 backend_dict['maxconn'] = line.split()[6] # 读取文件中server的maxconn 33 server_list.append(backend_dict.copy()) # 将backend中的信息加到server_list中,此处须要用copy 34 backend_all_dict[backend_name] = server_list # 将server信息对应backend存到字典中 35 36 return (backend_list,backend_all_dict) # 返回backend和server信息 37 38 39 def backend_show(backend_list): # 展现backend列表内容 40 backend_show_dict = {} 41 print("-------------------------------------------------") 42 print("\t\t\t欢迎来到HAproxy文件配置平台") 43 print("-------------------------------------------------") 44 print("backend列表信息以下:") 45 for k,v in enumerate(backend_list,1): # 逐行读取backend信息并展现 46 print(k, v) 47 backend_show_dict[str(k)] = v 48 return backend_show_dict # 返回backend和对应编号 49 50 51 def server_show(backend_input,backend_all_dict): # 展现backend下server内容 52 server_show_dict = {} 53 server_list = backend_all_dict[backend_input] 54 for k,v in enumerate(server_list,1): # 编号展现server信息 55 print(k,"name:",v['name'],"\tIP:",v['IP'],"\tweight:",v['weight'],"\tmaxconn:",v['maxconn']) 56 server_show_dict[k] = v 57 return server_show_dict # 返回编号对应的server字典 58 59 60 def action_list(): # 显示操做列表和编号,并返回操做编号 61 print("-------------------------------------------------") 62 print("操做清单以下:") 63 print(''' 64 1.查询backend和server信息 65 2.添加backend和server信息 66 3.修改backend和server信息 67 4.删除backend和server信息 68 5.退出 69 ''') 70 print("-------------------------------------------------") 71 action_num = numif(input("请输入须要操做的编号:(请输入数字)")) 72 return action_num 73 74 75 def inquiry(inquiry_input): # 定义查询功能 76 while True: 77 if inquiry_input in backend_show_dict: # 编号输入分支 78 backend_input = backend_show_dict[inquiry_input] # 输入编号获得backend 79 print(backend_input, ":") 80 server_show(backend_input, backend_all_dict) # 调用server_show,展现backend下server 81 break 82 83 elif inquiry_input in backend_show_dict.values(): # backend名称输入分支 84 print(inquiry_input, ":") 85 server_show(inquiry_input, backend_all_dict) # 调用server_show,展现backend下server 86 break 87 88 else: # 校验异常输入 89 inquiry_input = input("输入错误,请从新输入:") 90 91 92 def add(add_input,file): # 定义添加功能 93 (backend_list, backend_all_dict) = show_list(file) 94 while True: 95 if add_input in backend_show_dict: #添加原有backend下server 96 add_dict = {} 97 add_dict['name'] = input("请输入需增长server名称:") 98 add_dict['IP'] = input("请输入需增长IP地址:") 99 add_dict['weight'] = input("请输入需增长weight值:") 100 add_dict['maxconn'] = input("请输入需增长maxcoon值:") 101 backend_name_add = backend_list[int(add_input)-1] 102 103 for dict in backend_all_dict[backend_name_add]: # 实现IP已存在,更新weight信息和maxconn信息 104 if add_dict['IP'] in dict.values(): 105 dict['weight'] = add_dict['weight'] 106 dict['maxconn'] = add_dict['maxconn'] 107 break 108 109 else: # IP不存在,就将server增长到backend下 110 backend_all_dict[backend_name_add].append(add_dict) 111 112 backup(file,backend_name_add,backend_all_dict) # 调用backup函数,将新增内容读写到文件中 113 print('''name:%s IP:%s weight:%s maxconn:%s已添加成功'''%( 114 add_dict['name'],add_dict['IP'],add_dict['weight'],add_dict['maxconn'])) # 提示添加成功 115 break 116 117 else: # 添加新backend下的server 118 add_dict = {} 119 add_dict['name'] = input("请输入%s下新增server名称:"%add_input) 120 add_dict['IP'] = input("请输入%s下新增IP地址:"%add_input) 121 add_dict['weight'] = input("请输入%s下新增weight值:"%add_input) 122 add_dict['maxconn'] = input("请输入%s下新增maxcoon值:"%add_input) 123 backend_name_add = add_input 124 backend_all_dict[backend_name_add] = add_dict # 将新增backend和对应server存到字典中 125 126 file_new = "%s_new" % file # 新建一个文件,用来新增数据 127 with open(file, 'r') as f_read, open(file_new, 'a+') as f_write: # 读取file文件,追加backend信息 128 for line in f_read: 129 f_write.write(line) 130 f_write.write("\nbackend %s" % backend_name_add) # 追加backend信息 131 server_line_write = '\n\t\tserver {name} {IP} weight {weight} maxconn {maxconn}\n' # 追加server信息 132 f_write.write(server_line_write.format(**add_dict)) # 格式化输出 133 134 os.system('mv %s %s_backup' % (file, file)) # 将file文件名改成file_backup 135 os.system('mv %s %s' % (file_new, file)) # 将file_new文件名改成file,实现备份 136 print("\nbackend %s" % backend_name_add) 137 print('''name:%s IP:%s weight:%s maxconn:%s已添加成功''' % ( 138 add_dict['name'], add_dict['IP'], add_dict['weight'], add_dict['maxconn'])) # 提示添加成功 139 break 140 141 142 def revise(revise_input): # 定义修改功能 143 revise_dict = {} 144 if revise_input in backend_show_dict: # 判断输入是否存在 145 backend_revise = backend_show_dict[revise_input] # 经过编号获取backend 146 revise_choise = input("是否须要修改该backend名称:%s;确认请按'y',按任意键继续:"%backend_revise) # 确认是否修改backend名,输入y修改,不然继续修改 147 if revise_choise == 'y': 148 backend_revise_new = input("请输入修改后的backend名:") # 修改backend名 149 backend_all_dict[backend_revise_new] = backend_all_dict.pop(backend_revise) # 将旧backend的server对应到修改后的backend上 150 revise_choise_server = input("是否须要继续修改%s下的server:确认请按'y',按任意键继续:"%backend_revise_new) # 询问是否继续修改 151 if revise_choise_server == 'y': # 继续修改server 152 server_revise_dict = server_show(backend_revise_new, backend_all_dict) # 展现server信息 153 server_revise_num = numif(input("请输入须要修改的server编号:")) # 获取须要修改的server编号 154 revise_dict['name'] = input("请输入修改后的name:") 155 revise_dict['IP'] = input("请输入修改后的IP:") 156 revise_dict['weight'] = input("请输入修改后的weight:") 157 revise_dict['maxconn'] = input("请输入修改后的maxconn:") 158 server_revise_dict[int(server_revise_num)] = revise_dict # 经过编号修改server信息 159 server_revise_dict_backup = {} 160 server_revise_dict_backup[backend_revise_new] = server_revise_dict.values() # 将修改的server信息对应到修改后的backend存到字典中 161 backup(file, backend_revise, server_revise_dict_backup,backend_revise_new) # 调用backup函数,操做文件 162 163 else: # 不修改server,只修改了backend 164 backup(file, backend_revise, backend_all_dict,backend_revise_new) 165 else: # 未修改backend名状况时修改server信息 166 server_revise_dict = server_show(backend_revise, backend_all_dict) 167 server_revise_num = numif(input("请输入须要修改的server编号:")) # 获取需修改的server编号 168 revise_dict['name'] = input("请输入修改后的name:") 169 revise_dict['IP'] = input("请输入修改后的IP:") 170 revise_dict['weight'] = input("请输入修改后的weight:") 171 revise_dict['maxconn'] = input("请输入修改后的maxconn:") 172 server_revise_dict[int(server_revise_num)] = revise_dict # 修改的server信息对应到编号中存到字典中 173 server_revise_dict_backup = {} 174 server_revise_dict_backup[backend_revise] = server_revise_dict.values() # 将修改后的server信息对应backend存到字典中 175 backup(file,backend_revise,server_revise_dict_backup) # 调用backup函数,操做文件 176 else: # 输入错误提示从新输入 177 revise_input_return = input("需修改backend不存在,请从新输入:") 178 revise(revise_input_return) 179 180 181 def delete(delete_input): # 定义删除功能 182 if delete_input in backend_show_dict: 183 backend_delete = backend_show_dict[delete_input] 184 delete_choise = input("是否须要删除该backend:%s;确认请按'y',按任意键继续:"%backend_delete) 185 if delete_choise == 'y': # 判断是否删除backend信息 186 del backend_all_dict[backend_delete] # 在backend与server总字典中删除backend 187 backup(file, backend_delete, backend_all_dict) # 调用backup函数,操做文件 188 189 else: # 删除server 190 server_delete_dict = server_show(backend_delete, backend_all_dict) 191 server_delete_num = int(numif(input("请输入须要删除的server编号:"))) # 除判断是否时数字外,还需转换为整数型 192 while True: # 删除backend下的server循环 193 if server_delete_num in server_delete_dict: # 判断输入编号是否存在 194 server_delete_dict.pop(server_delete_num) 195 server_delete_dict_backup = {} 196 server_delete_dict_backup[backend_delete] = server_delete_dict.values() 197 backup(file, backend_delete, server_delete_dict_backup) # 调用backup函数,操做文件 198 break 199 else: 200 server_delete_num = input("输入编号不存在,请从新输入:") # 提示输入错误 201 202 203 def backup(file,backend_name_action,backend_backup_dict,*backend_name_revise): # 定义文档备份与回写功能 204 file_new = "%s_new"%file 205 add_flag = False # 为跳过原backend下server存在 206 with open(file,'r') as f_read , open(file_new,'w+') as f_write: # 同时打开读文件和写文件 207 for line in f_read: # 读取每行信息 208 backend_name = "backend %s" % backend_name_action 209 backend_name_revise = "".join(tuple(backend_name_revise)) # 修改功能会传参,将元组转换为字符串 210 if line.strip() == backend_name: # 读取某行中有参数中的backend 211 if backend_name_action not in backend_backup_dict and backend_name_revise not in backend_backup_dict: # 为了删除backend而存在 212 add_flag = True 213 pass 214 215 elif backend_name_revise in backend_backup_dict: # 判断修改功能中修改后backend存在与字典中 216 line_revise = "backend %s\n" % backend_name_revise 217 f_write.write(line_revise) 218 for add_dict in backend_backup_dict[backend_name_revise]: # 逐行读取修改backend下的server信息 219 server_line_write = '\t\tserver {name} {IP} weight {weight} maxconn {maxconn}\n' 220 f_write.write(server_line_write.format(**add_dict)) # 格式化输出 221 add_flag = True 222 223 else: 224 f_write.write(line) # 将此行写在文件中 225 for add_dict in backend_backup_dict[backend_name_action]: # 读取该backend下全部server信息 226 server_line_write = '\t\tserver {name} {IP} weight {weight} maxconn {maxconn}\n' 227 f_write.write(server_line_write.format(**add_dict)) 228 add_flag = True 229 230 elif line.strip().startswith("server") == True and add_flag == True: # 为了跳过原backend下的server 231 pass 232 233 else: # 写无用行 234 f_write.write(line) 235 add_flag = False # 写下无用行后能够继续循环 236 237 os.system('mv %s %s_backup' % (file, file)) 238 os.system('mv %s %s' % (file_new, file)) 239 240 241 def backend_exit(): #定义退出功能 242 flag_exit = True 243 b_input = input("操做完毕退出请按'b':") 244 while flag_exit: 245 if b_input == 'b': 246 flag_exit = False 247 return flag_exit 248 249 else: 250 return backend_exit() #使用尾递归优化,加上return帮助直接退出,而不须要递归一层层退出 251 252 253 flag = True # 主函数开始 254 while flag: 255 flag_main = True 256 flag_action = True 257 file = 'haproxy' # 文件名赋值 258 (backend_list, backend_all_dict) = show_list(file) # 调用show_list函数获取backend和server信息 259 backend_show_dict = backend_show(backend_list) # 展现backend信息 260 action_num = action_list() # 展现功能项,并输入操做编号 261 while flag_main: 262 if action_num == '1': 263 inquiry(input("请输入须要查询的backend编号或名称:")) 264 flag_main = backend_exit() 265 break 266 267 if action_num == '2': 268 add(input("请输入须要添加的现有backend编号或新backend名称:"), file) 269 flag_main = backend_exit() 270 break 271 272 if action_num == '3': 273 revise(input("请输入须要修改的backend编号或名称:")) 274 flag_main = backend_exit() 275 break 276 277 if action_num == '4': 278 delete(input("请输入须要删除的backend编号或名称:")) 279 flag_main = backend_exit() 280 break 281 282 if action_num == '5': 283 sys.exit() 284 285 elif action_num not in range(5): # 当输入不在编号中,提示并从新输入 286 print("\033[31;1m输入错误请从新输入!\033[0m") 287 flag_main = False
1.字符编码与转码
详细文章:
http://www.cnblogs.com/linhaifeng/articles/5950339.html 林海峰老师
http://www.cnblogs.com/yuanchenqi/articles/5956943.html(中文博客整理)
http://www.diveintopython3.net/strings.html(英文文档)
需知:
1.在python2默认编码是ASCII, python3里默认是unicode
2.unicode 分为 utf-32(占4个字节),utf-16(占两个字节),utf-8(占1-4个字节), so utf-16就是如今最经常使用的unicode版本, 不过在文件里存的仍是utf-8,由于utf8省空间
3.在py3中encode,在转码的同时还会把string 变成bytes类型,decode在解码的同时还会把bytes变回string
GBK-->UTF-8的转换,依靠unicode来进行(以下图,是适合py2.x,学Py3的也能够做为了解!):
2.字符编码与转码的实例
1):基于py2.7:
1 #Author:http://www.cnblogs.com/Jame-mei 2 #-*-coding:utf-8-*- 3 #注意,基于py2.7必需要加utf-8的解释器 4 5 import sys 6 7 print (sys.getdefaultencoding()) 8 9 ''' 10 #1.utf-8 转换成gbk 11 s = '您好' 12 s_to_unicode=s.decode('utf-8') 13 print (s_to_unicode) 14 s_to_gbk=s_to_unicode.encode("gbk") 15 print (s_to_gbk)#这个在linux终端显示上调整为gbk,才能显示。 16 17 18 #2.gbk转换成utf-8 19 gbk_to_utf8=s_to_gbk.decode("gbk").encode("utf-8") 20 print(gbk_to_utf8) 21 22 ''' 23 24 ''' 25 #简易版:utf-8转出成gbk 26 #utf-8是unicode的扩展集,是能够直接打印的,gbk和unicode必需要通过转换才行。 27 s=u'您好' #将utf-8直接转换成unicode编码! 28 print(s) 29 s_to_gbk=s.encode("gbk") 30 print (s_to_gbk)#这个在linux终端显示上调整为gbk,才能显示。 31 32 33 #2.gbk转换成utf-8 34 gbk_to_utf8=s_to_gbk.decode("gbk").encode("utf-8") 35 print(gbk_to_utf8) 36 ''' 37 38 39 40 #3.utf-8转换成gb2312 41 s="您好" 42 s_gb2312=s.decode("utf-8").encode("gb2312") 43 print (s_gb2312) 44 45 #4.gb2312转换成gbk 46 gb2312_to_gbk=s_gb2312.decode("gb2312").encode("gbk") 47 print (gb2312_to_gbk) 48 49 50 51 #5.utf-8转换成gbk 52 gb2312_to_utf=s.decode("utf-8").encode("gbk") 53 print (gb2312_to_gbk)
2):基于py3.6:
1 #Author:http://www.cnblogs.com/Jame-mei 2 #-*-coding:utf-8-*- 3 #基于python3.x版本 4 5 import sys 6 print (sys.getdefaultencoding()) 7 8 #1.将utf-8转换成gbk 9 ''' 10 str="你哈" 11 str_gbk=str.encode("gbk") 12 print (str_gbk) 13 #encode("gbk"):b'\xc4\xe3\xb9\xfe' 14 #encode()为默认utf-8:b'\xe4\xbd\xa0\xe5\x93\x88' 15 16 17 2.将gbk转成utf-8 18 gbk_to_utf8=str_gbk.decode("gbk").encode("utf-8") 19 print (gbk_to_utf8) 20 ''' 21 22 #3.py3.x中将utf-8转换成gb2312 23 s="我爱北京天安门" 24 s_gb2312=s.encode("gb2312") #默认就是unicode,不用再decode,喜大普奔 25 print (s_gb2312) 26 27 #4.而后将gb2312转换成utf-8 28 gb2312_to_unicode=s_gb2312.decode("gb2312") 29 print (gb2312_to_unicode) 30 31 unicode_to_utf8=s_gb2312.decode("gb2312").encode("utf-8") 32 print (unicode_to_utf8) 33 34 ''' 35 总结: 36 python3.x默认为2种数据类型:默认unicode和bytes类型,其中utf-8为unicode的扩展,因此utf-8能够直接encode("gbk")转换成gbk 37 可是gbk不能直接转换成utf-8,须要decode("gbk")再encode("utf-8")才行。 38 39 python3中,将unicode转换成gbk,utf8,gb2312类型的时候,同时显示为bytes类型。 40 ''' 41 42 43 ''' 44 思考区: 45 str="你哈" #这里python默认数据类型为unicode编码,coding:gbk只是修改了文件的编码方式。 46 print (str.encode('gbk')) 47 print (str.encode('utf-8')) 48 print (str.encode('utf-8').decode('utf-8').encode('gb2312')) #转换成gb2312,与gbk的bytes结果同样,是由于gbk向下兼容gb2312! 49 50 51 52 '''
3.若是对编码格式仍是迷茫,请看看alex的鸡汤文:
1)先说python2:
2)再说python3:
编码应用比较多的场景应该是爬虫了,互联网上不少网站用的编码格式很杂,虽然总体趋向都变成utf-8,但如今仍是很杂,因此爬网页时就须要你进行各类编码的转换,不过生活正在变美好,期待一个不须要转码的世界。
最后,编码is a piece of fucking shit, noboby likes it.
1.函数基本语法及特性
函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不一样的,具体区别,咱们后面会讲,编程中的函数在英文中也有不少不一样的叫法。在BASIC中叫作subroutine(子过程或子程序),在Pascal中叫作procedure(过程)和function,在C中只有function,在Java里面叫作method。
特性:
1
2
3
4
|
def sayhi(): #函数名
print ( "Hello, I'm nobody!" )
sayhi() #调用函数
|
能够带参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#下面这段代码
a,b = 5 , 8
c = a * * b
print (c)
#改为用函数写
def calc(x,y):
res = x * * y
return res #返回函数执行结果
c = calc(a,b) #结果赋值给c变量
print (c)
|
2.函数的应用场景:
1 #Author:http://www.cnblogs.com/Jame-mei 2 3 def func1(): 4 '''定义一个函数:test1''' 5 print ('in the func1') 6 return 0 7 8 9 def fun2(): 10 '''定义一个过程(没有返回值的函数!):test2''' 11 print ('in the func2') 12 13 14 15 x=func1() 16 17 y=fun2() 18 19 print ('func1 return is %s' %x) 20 #print('func1 return is {_x}'.format(_x=x)) 与%s输出相同 21 #func1 return is 0 22 23 print ('func2 return is {_y}'.format(_y=y)) 24 #func2 return is None
1 #Author:http://www.cnblogs.com/Jame-mei 2 import time 3 4 def logger(): 5 #time_format='%Y-%m-%d %X' ===>%F %X 6 time_format='%F %X' 7 time_current=time.strftime(time_format) 8 with open('test_def','a+') as f: 9 f.write("%s end action\n" %time_current) #2.可扩展 10 11 def test1(): 12 print ('in the test1') 13 logger() #1.代码重用,3.一致性等 14 15 def test2(): 16 print ('in the test2') 17 logger() 18 19 def test3(): 20 print ('in the test3') 21 logger() 22 23 24 test1() 25 test2() 26 test3()
1 如今老板让你写一个监控程序,监控服务器的系统情况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏空了全部的知识量,写出了如下代码 2 3 while True: 4 if cpu利用率 > 90%: 5 #发送邮件提醒 6 链接邮箱服务器 7 发送邮件 8 关闭链接 9 10 if 硬盘使用空间 > 90%: 11 #发送邮件提醒 12 链接邮箱服务器 13 发送邮件 14 关闭链接 15 16 if 内存占用 > 80%: 17 #发送邮件提醒 18 链接邮箱服务器 19 发送邮件 20 关闭链接 21 上面的代码实现了功能,但即便是邻居老王也看出了端倪,老王亲切的摸了下你家儿子的脸蛋,说,你这个重复代码太多了,每次报警都要重写一段发邮件的代码,太low了,这样干存在2个问题: 22 23 代码重复过多,一个劲的copy and paste不符合高端程序员的气质 24 若是往后须要修改发邮件的这段代码,好比加入群发功能,那你就须要在全部用到这段代码的地方都修改一遍 25 你以为老王说的对,你也不想写重复代码,但又不知道怎么搞,老王好像看出了你的心思,此时他抱起你儿子,笑着说,其实很简单,只须要把重复的代码提取出来,放在一个公共的地方,起个名字,之后谁想用这段代码,就经过这个名字调用就好了,以下 26 27 28 def 发送邮件(内容) 29 #发送邮件提醒 30 链接邮箱服务器 31 发送邮件 32 关闭链接 33 34 while True: 35 36 if cpu利用率 > 90%: 37 发送邮件('CPU报警') 38 39 if 硬盘使用空间 > 90%: 40 发送邮件('硬盘报警') 41 42 if 内存占用 > 80%: 43 发送邮件('内存报警') 44 45 46 你看着老王写的代码,气势恢宏、磅礴大气,代码里透露着一股内敛的傲气,心想,老王这我的真是不通常,忽然对他的背景更感兴趣了,问老王,这些花式玩法你都是怎么知道的? 老王亲了一口你儿子,捋了捋不存在的胡子,淡淡的讲,“老夫,年少时,师从京西沙河淫魔银角大王 ”, 你一听“银角大王”这几个字,不禁的娇躯一震,心想,真nb,怪不得代码写的这么6, 这“银角大王”当年在江湖上但是数得着的响当当的名字,只惋惜后期纵欲过分,卒于公元2016年, 真是惋惜了,只留下其哥哥孤守当年兄弟俩一块儿打下来的江山。 此时你看着的老王离开的身影,感受你儿子跟他愈来愈像了。。。
1 #Author:http://www.cnblogs.com/Jame-mei 2 #注释:函数的返回值的实例 3 4 def test1(): 5 print ('in the test1') 6 #output:in the test1,下面的print就不输出了,由于遇到了return 7 return 0 8 #print ('in the test2') 9 10 11 def test2(): 12 print ('in the test2') 13 return test3() #把test3()函数做为返回值,也叫高阶函数! 14 15 def test3(): 16 print ('in the test3') 17 return 1,'hello',['alex','jame','oldboy'],{'alex':28,'oldboy':45,'jame':27},(2,3,4,5) 18 19 def test4(): 20 print ('in the test4') 21 22 23 x=test1() 24 y=test2() 25 z=test3() 26 m=test4() 27 28 print (x) 29 #0 30 31 print (y) 32 ##(1, 'hello', ['alex', 'jame', 'oldboy'], {'alex': 28, 'oldboy': 45, 'jame': 27}, (2, 3, 4, 5)) 33 34 print (z)#把字符串,数字,列表,字典,元祖都返回到一个元祖里。 35 #(1, 'hello', ['alex', 'jame', 'oldboy'], {'alex': 28, 'oldboy': 45, 'jame': 27}, (2, 3, 4, 5)) 36 37 38 print (m) #没有return,则返回None 39 40 函数的返回值
总结:
1).不一样返回值类型
*函数中没有return ,返回None。
*函数中 return 返回中只有1个变量时候,为返回值为object对象。
例如return (2),return [2],return 'hello'分别返回是2,[2],hello单个元素。
*函数中 return 返回中有多个变量时候,会把多个变量包含在一个元祖中,返回一个元祖!
例如 return (2,) ,返回的一个元祖(2,) return 2,'hello',(2,3,4) ,返回(2, 'hello', (2, 3, 4)) 元祖。
*函数中 return另一个函数test3(),则返回只test3()的返回值
(2, 'hello', (2, 3, 4))
2).函数为何要返回值?
为后面的程序调用,经过返回值的来进行判断,从而完成相关代码的逻辑。
形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。所以,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量。
实参能够是常量、变量、表达式、函数等,不管实参是何种类型的量,在进行函数调用时,它们都必须有肯定的值,以便把这些值传送给形参。所以应预先用赋值,输入等办法使参数得到肯定值。
形参和实参的区别:形参是虚拟的,不占用内存,形参变量只有在被调用的时候才分配内存。实参是一个变量,占用内存空间,数据传送单向,实参传给形参,形参不能传给实参!
1):默认参数
默认参数的特色:调用函数时候,默认参数非必须传(能够默认不写,也能够用位置参数从新赋值,也能够在最后用关键字从新赋值)
默认参数的用途:1.默认安装参数 2.默认端口参数等等预设的默认。
1 1默认参数 2 def stu_register01(name, age, country, course): 3 print("----注册学生信息------") 4 print("姓名:", name) 5 print("age:", age) 6 print("国籍:", country) 7 print("课程:", course) 8 9 stu_register01("王山炮", 22, "CN", "python_devops") 10 stu_register01("张叫春", 21, "CN", "linux") 11 12 output: 13 ----注册学生信息------ 14 姓名: 王山炮 15 age: 22 16 国籍: CN 17 课程: python_devops 18 ----注册学生信息------ 19 姓名: 张叫春 20 age: 21 21 国籍: CN 22 课程: linux 23 24 25 26 #===================>改造为默认参数调用,默认参数必须放在最后,调用的时候也须要按照顺序。 27 def stu_register02(name, age,course,country="CN"): 28 print("----注册学生信息------") 29 print("姓名:", name) 30 print("age:", age) 31 print("国籍:", country) 32 print("课程:", course) 33 34 stu_register02("张叫春", 21, "CN", "linux") #逻辑错误,默认值会被课程覆盖,顺序很重要。 35 stu_register02("金妍希", 21,"舞蹈") #不填写国籍,默认中国 36 stu_register02("Tom", 22,"python_devops",country="US") #修改默认国籍 37 38 output: 39 ----注册学生信息------ 40 姓名: 张叫春 41 age: 21 42 国籍: linux 43 课程: CN #这里会被覆盖!! 44 ----注册学生信息------ 45 姓名: 金妍希 46 age: 21 47 国籍: CN 48 课程: 舞蹈 49 ----注册学生信息------ 50 姓名: Tom 51 age: 22 52 国籍: US 53 课程: python_devops
2):位置参数 和 3)关键字参数
1 def test(x,y): 2 print (x) 3 print (y) 4 5 6 #1.位置参数调用(与形参顺序一一对应!) 7 test(1,2) 8 9 #2.关键字参数调用(与形参顺序无关,与关键字对应!) 10 test(y=3,x=4) 11 12 #3.既有位置参数又有关键字参数,以位置参数优先!! 13 #3.1.关键字+位置参数(执行错误,第一个为关键字参数调用,第二个参数也应该是关键字才行!) 14 test(x=1,4) 15 16 17 #3.2.位置参数+关键字混用 18 test(3,y=5) #(执行正确,第一个参数与位置相关,第二个必需要位置参数的值,或者关键参数y=...) 19 #test(3,x=4) #(执行错误,第一个参数与位置相关,关键参数应该顺序是y=...) 20 21 22 23 #4.大于2个位置参数和关键参数的混用状况,关键参数不能写在位置参数前面的! 24 def test2(x,y,z): 25 print (x,y,z) 26 27 #test2(3,y=2,6) #执行错误,关键字参数应该放在位置参数后面. 28 #test2(1,2,x=3) #执行错误,最后一个只能是z. 29 test2(1,2,z=3) #执行正确,最后一个参数对应为z 30 test2(1,z=3,y=2) #执行正确,后面两个都为关键字参数与顺序无关 31 32 33 34 #以上实例多练习体会其中的原理!不一一帖出来了。
4):参数组(非固定参数)
1): *args :把N个参数转换成元祖的方式,其中*args接受N个位置参数!
1 def test3(*args): #*args也能够自定义为 *jame 2 print(args) 3 4 test3(1,2,3,4,5) #获得一个元祖(1,2,3,4,5) 5 6 test3(*['a','b']) #至关于*args=*['a','b'],获得('a', 'b') 7 8 test3(['x','y','z'],['1','2','3']) 9 #至关于args=tunple(['x','y','z']),获得(['x', 'y', 'z'],) 10 #当为2个列表时候,获得, (['x','y','z'],['1', '2', '3']) 11 12 13 14 #x位置参数不能放在 *args后面!! 15 def test4(x,*args): 16 print (x) 17 print (args) 18 19 test4(1,'a','b',2,3,4) 20 ''' 21 output: 22 1 23 ('a', 'b', 2, 3, 4) 24 '''
2): **kwargs:把N个参数转换成字典的方式,其中**kwargs接受N个关键字参数!
1 def test4(**kwargs): 2 print (kwargs) 3 print(kwargs['name']) #输出字典的key-value! 4 print (kwargs['age']) 5 print (kwargs['sex']) 6 7 8 #方式1 9 test4(name='jame',age='27',sex='男',address='Shanghai') 10 ''' 11 output: 12 输出一个字典 13 {'name': 'jame', 'age': '27', 'sex': '男', 'address': 'Shanghai'} 14 jame 15 27 16 男 17 ''' 18 19 #方式2 20 test4(**{'name':'tom','age':8,'sex':'女'}) #**{}==**kwargs 21 ''' 22 output: 23 {'name': 'tom', 'age': 8} 24 tom 25 8 26 女 27 '''
3): **kwargs与位置参数混用,**kwargs放在位置参数的后面。
1 def test5(name,**kwargs): 2 print (name) 3 print (kwargs) 4 5 #1.只填写位置参数name,**kwargs省略输出一个控的字典 6 test5('Jack') 7 ''' 8 output: 9 Jack 10 {} 11 ''' 12 13 14 #2.位置参数和**kwargs都填写,注意age,sex不带''/"",不要跟字典搞混淆了。 15 test5('kater',age=18,sex='boy') 16 17 ''' 18 output: 19 kater 20 {'age': 18, 'sex': 'boy'} 21 22 ''' 23 24 25 #3.位置参数和**kwargs做为一个字典的方式和2.结果同样,感受更加清晰! 26 27 test5('Alice',**{'age':16,'sex':'girl'}) 28 ''' 29 output: 30 Alice 31 {'age': 16, 'sex': 'girl'} 32 '''
4):顺序参数,默认参数和**kwargs混用(优先级:顺序参数>默认参数>**kwargs关键字参数)
1 def test06(name,**kwargs,age=18): #报错,age=18默认参数不能放在最后,参数组(关键字参数)必定要日后放! 2 3 def test06(name,age=18,**kwargs): 4 print(name,age,kwargs) 5 6 7 test06('python',20,sex='unknow',address='US') #age为默认值能够不写,也能够写20,为了易读性最好写age=30等等 8 ''' 9 output: 10 python 11 20 12 {'sex': 'unknow', 'address': 'US'} 13 ''' 14 15 16 #test06('python',20,sex='unknow',address='US',age=38) 17 # #前面若是给默认值赋值了,再**kwargs中指定关键字age则报错!!尽可能不要这么写,容易歧义混乱! 18 19 20 test06('python',sex='unknow',address='US',age=38) #不写age,在**kwargs后面参数中又指定了age=38,最后替代默认值20 21 ''' 22 output: 23 python 38 {'sex': 'unknow', 'address': 'US'} 24 25 '''
5):顺序参数,默认值参数,*args , **kwargs混用( 优先级: 顺序参数 > 默认值参数 > *args(接受位置参数) > **kwargs(接受关键字参数) )
1 def test07 (name,age=18,*args,**kwargs): 2 print (name) 3 print (age) 4 print (args) 5 print (kwargs) 6 7 8 test07('dog',20,sex='unknow',address='doghome') 9 ''' 10 输出: 11 dog 12 20 13 () #由于*args接受的是位置参数,不能是关键字参数,因此为空! 14 {'sex': 'unknow', 'address': 'doghome'} 15 ''' 16 17 test07('cat',9,1,2,3,sex='catgirl',adress='cathome') 18 ''' 19 输出: 20 cat 21 9 22 (1, 2, 3) 23 {'sex': 'catgirl', 'adress': 'cathome'} 24 '''
函数是Python内建支持的一种封装,咱们经过把大段代码拆成函数,经过一层一层的函数调用,就能够把复杂任务分解成简单的任务,这种分解能够称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。
函数式编程中的函数这个术语不是指计算机中的函数(其实是Subroutine),而是指数学中的函数,即自变量的映射。也就是说一个函数的值仅决定于函数参数的值,不依赖其余状态。好比sqrt(x)函数计算x的平方根,只要x不变,不论何时调用,调用几回,值都是不变的。
Python对函数式编程提供部分支持。因为Python容许使用变量,所以,Python不是纯函数式编程语言。
简单说,"函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论。
主要思想是把运算过程尽可能写成一系列嵌套的函数调用。举例来讲,如今有这样一个数学表达式:
(1 + 2) * 3 - 4
传统的过程式编程,可能这样写:
var a = 1 + 2;
var b = a * 3;
var c = b - 4;
函数式编程要求使用函数,咱们能够把运算过程定义为不一样的函数,而后写成下面这样:
var result = subtract(multiply(add(1,2), 3), 4);
这段代码再演进如下,能够变成这样
add(1,2).multiply(3).subtract(4)
这基本就是天然语言的表达了。再看下面的代码,你们应该一眼就能明白它的意思吧:
merge([1,2],[3,4]).sort().search("2")
所以,函数式编程的代码更容易理解。
要想学好函数式编程,不要玩py,玩Erlang,Haskell,
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
1 #Author:http://www.cnblogs.com/Jame-mei 2 3 school='oldboy linux' #定义全局变量 4 5 #局部变量和全局变量 6 def change_name(name): 7 global school #强制声明修改全局变量! 8 school='Mage linux' 9 print ('Before change',name,school) 10 name='Alex Li' #局部变量,做用域在函数内部生效。 11 print ('After change',name) 12 age=12 13 14 15 name='Jame' 16 change_name(name) 17 print (name) #依然是Jame,没有发生变化。 18 #print (age) #NameError: name 'age' is not defined,局部变量做用域只在函数change_name中。 19 20 print ('global school:',school) #全局变量由oldboy linux--->mage linux
实例2:编程规范 禁止在函数内部修改/定义 global 全局变量!
1 def change_name(): 2 global name 3 name='Jame-mei' 4 5 6 change_name() 7 print (name) 8 输出: 9 Jame-mei
实例3:编程规范 禁止修改global全局变量(单独的字符串和整数),列表、字典、集合、类等复杂数据类型能够修改。
1 names=['Alex','oldboy','mage'] 2 def change_name(): 3 names[0]='金角大王' 4 print (names) 5 6 7 change_name() #全局变量 8 9 10 #字符串,整数不能够修改,其余的能够修改! 11 #列表,字典,集合,类等能够修改。
在函数内部,能够调用其余函数。若是一个函数在内部调用自身自己,这个函数就是递归函数。
函数递归调用,在调用一个函数的过程当中又直接或间接地调用了本身称之为函数的递归调用
本质就是一个重复的过程,必须有两个明确的阶段
#一、回溯:一层一层地递归调用下去,没进入下一层问题的规模都应该有所减小
#二、递推:递归必需要有一个明确的结束条件,在知足该条件的状况下会终止递归,
往回一层一层地结束调用
递归特性:
1. 必须有一个明确的结束条件。
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减小。
3. 递归效率不高,递归层次过多会致使栈溢出(在计算机中,函数调用是经过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。因为栈的大小不是无限的,因此,递归调用的次数过多,会致使栈溢出)
堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html
实例1:栈内存溢出实例保护机制
1 def calc(n): 2 print (n) 3 return calc(n+1) 4 5 6 calc(1) 7 8 输出: 9 991 10 992 11 993 12 994 13 995 14 996 15 997 16 998Traceback (most recent call last): 17 File "E:/pythonwork/s14/day03/def_digui.py", line 11, in <module> 18 calc(1) 19 File "E:/pythonwork/s14/day03/def_digui.py", line 7, in calc 20 return calc(n+1) 21 File "E:/pythonwork/s14/day03/def_digui.py", line 7, in calc 22 return calc(n+1) 23 File "E:/pythonwork/s14/day03/def_digui.py", line 7, in calc 24 return calc(n+1) 25 [Previous line repeated 993 more times] 26 File "E:/pythonwork/s14/day03/def_digui.py", line 6, in calc 27 print (n) 28 RecursionError: maximum recursion depth exceeded while calling a Python object
实例2:给递归一个结束条件
1 def calc(n): 2 print(n) 3 if int(n/2) >0: 4 return calc(int(n/2)) 5 print (n) 6 7 8 9 calc(10) 10 11 12 输出: 13 10 14 5 15 2 16 1 17 1 18 19 Process finished with exit code 0
4.递归 vs while 循环
递归只须要把控住结束或进入递归的条件便可,至于循环次数或者嵌套的层数无需考虑。
''' # 直接 # import sys # print(sys.getrecursionlimit()) # sys.setrecursionlimit(10000) # def foo(n): # print('from foo',n) # foo(n+1) # # foo(0) # 间接 # def bar(): # print('from bar') # foo() # # def foo(): # print('from foo') # bar() # # foo() # def foo(): # print('from foo') # foo() # # foo() # age(5) = age(4) + 2 # age(4) = age(3) + 2 # age(3) = age(2) + 2 # age(2) = age(1) + 2 # age(1) = 18 # age(n) = age(n-1) + 2 #n > 1 # age(n) = 18 #n=1 # # def age(n): # if n == 1: # return 18 # return age(n-1) + 2 # # # print(age(5)) # l=[1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]] # # def tell(l): # for item in l: # if type(item) is list: # #item 是列表 # # 再次调用自己的逻辑,传入item # tell(item) # else: # #item是单独的元素 # print(item) # # tell(l) # 数字列表,数字是从小到大排列的 nums=[3,11,13,15,23,27,43,51,72,81,93,101] # 算法:就是如何高效地解决某一个具体问题的方法 # l1=[3,11,13,15,23,27] # l2=[23,27] # l3=[23] def binary_search(nums,find_num): print(nums) if len(nums) == 0: print('not exists') return mid_index=len(nums) // 2 if find_num > nums[mid_index]: # in the right nums=nums[mid_index+1:] # 重复调用自己的逻辑,传入新的nums binary_search(nums,find_num) elif find_num < nums[mid_index]: # in the left nums=nums[:mid_index] # 重复调用自己的逻辑,传入新的nums binary_search(nums,find_num) else: print('find it') binary_search(nums,94)
1.高阶函数
变量能够指向函数,函数的参数能接收变量,那么一个函数就能够接收另外一个函数做为参数,这种函数就称之为高阶函数。
def
add(x,y,f):
return
f(x)
+
f(y)
res
=
add(
3
,
-
6
,
abs
)
print
(res)
2.匿名函数
匿名函数就是不须要显式的指定函数
1
2
3
4
5
6
7
8
|
#这段代码
def calc(n):
return n * * n
print (calc( 10 ))
#换成匿名函数
calc = lambda n:n * * n
print (calc( 10 ))
|
你也许会说,用上这个东西没感受有毛方便呀,若是是这么用,确实没毛线改进,不过匿名函数主要是和其它函数搭配使用的呢,以下
1
2
3
|
res = map ( lambda x:x * * 2 ,[ 1 , 5 , 7 , 4 , 8 ])
for i in res:
print (i)
|
输出:
1
25
49
16
64
3.匿名函数的实例操做
# 有名函数:能够经过名字重复使用 # def foo(): # print('from foo') # # foo() #匿名函数:临时用一次之后不会再用了 # def sum2(x,y): # return x + y # print(sum2) # sum2=lambda x,y:x + y # print(sum2) # res=sum2(1,2) # print(res) # 定义匿名函数就是定义出了一个函数的内存 # res=(lambda x,y:x + y)(1,2) # print(res) salaries={ 'egon':300000, 'alex':100000000, 'wupeiqi':10000, 'yuanhao':2000 } # print(max([11,22,33,44])) # print(max(salaries)) # def func(k): # return salaries[k] # print(max(salaries,key=lambda x:salaries[x])) # for k in salaries: # res=func(k) # 将func的返回值当作比较依据 # print(min(salaries,key=lambda x:salaries[x])) # num=[3,1,4,9] # l=sorted(num) # 默认从小到大排 # l=sorted(num,reverse=True) # 从大到小排 # print(l) # salaries={ # 'egon':300, # 'alex':100000000, # 'wupeiqi':10000, # 'yuanhao':2000 # } # 按照薪资高低排序人名 # print(sorted(salaries,key=lambda x:salaries[x])) # 了解 # map,reduce,filter # map:映射 names=['alex','lxx','wxx'] # chicken=map(lambda x:x+'_dsb',names) # print(chicken) # print(list(chicken)) # l=[name+'_dsb' for name in names] # print(l) # filter:过滤 # names=['alex_teacher','lxx_teacher','wxx_teacher','egon_boss'] # res=filter(lambda x:x.endswith('teacher'),names) #filter会"for循环"names,取出来每个名字,而后传给指定的函数,若是函数的返回值为True,则留下该名字 # for item in res: # print(item) # l=(name for name in names if name.endswith('teacher')) # print(list(l)) # reduce:合并 from functools import reduce l=['a','b','c','d','e'] # res=reduce(lambda x,y:x+y,l,'AAA') # #'AAA' + 'a'='AAAa' #'AAAa' + 'b' = 'AAAab' #'AAAab' + 'c' # print(res) # res=reduce(lambda x,y:x+y,l) #'a','b' # print(res) # res=reduce(lambda x,y:x+y,range(0,101)) # print(res)
固然此表你在文件存储时能够这样表示
1
|
1
,Alex Li,
22
,
13651054608
,IT,
2013
-
04
-
01
|
现须要对这个员工信息文件,实现增删改查操做
注意:以上需求,要充分使用函数,请尽你的最大限度来减小重复代码!
代码地址:https://gitee.com/meijinmeng/Sqltest.git