集合是一個無序的、不可重複的集合。主要做用有:html
1.去重,把一個列表變成集合,就等於去重了。
2.關係測試,測試兩組數據以前的交集、差集、並集等關係python
建立、交集、並集、差集、對稱差集、子集、父集 長度、判斷元素是否在集合中、刪除linux
# 建立集合: set1 = set([1,2,3,4,5,90]) set2 = set([2,378,98]) # 交集 (在set1和set2中都有的元素) print(set1.intersection(set2)) print(set1&set2) # 並 set1和set2的全部元素的集合 print(set1.union(set2)) print(set1|set2) # 差集 :在set1中不在set2中 print(set1.disfference(set2)) print(set1-set2) # 對稱差集 項在t或s中,但不會同時出如今兩者中 print(set1^set2) print(set1.symmetric_difference(set2)) # 子集 print(set1.issubset(set2)) # 父集 print(set1.issuperset(set2)) # 在set中添加一項 print(set1.add(45)) # 在set 中添加多項 print(set1.update(set2)) # remove刪除指定項,若不存在,會報錯 print(set1.remove(2)) print(set1.discard(2)) # remove刪除指定項,如不存在,不報錯 print(set1.pop()) # 刪除任意一項 set1.discard(98) # 集合的長度 print(len(set1)) x = '' if x in set1:# 判斷 x是否在set1 中。 pass if x not in set1:# 判斷集合不在set1中。 pass if set1.issubset(set2): # s <= t 測試是否s中的每個元素都在t中 pass
1.打開文件,獲得文件句柄並賦值給一個變量
2.經過句柄對文件進行操做
3.關閉文件git
f = open("yesterday",'r',encoding='utf-8') # 只可讀 f2 =open("yesterday2",'w',encoding="utf-8") # 可寫,覆蓋原來的內容 f3=open("yesterday2",'a',encoding="utf-8") # 追加不可讀 data = f.read() # 打印全部內容 f2.write("我愛北京天安門\n") f2.write("天安門\n") f4 = open("yesterday","a+",encoding='utf-8') # 新建文件 print(f4.readline()) # print(f4.readline()) # 讀一行 print(f4.encoding) # 打印文件句柄的編號方式 print(f4.tell()) # 顯示當前文件句柄的位置 print(f4.seek(10)) # 件句柄調到第10個位置, # 備註:在寫文件時,若是使用r+ ,w+,時,不使用seek時,在文件末尾追加寫入的內容 # 若使用,seek(),就覆蓋寫入了,不在使用追加模式 f4.truncate(10) # 從文件開頭到10 截斷 f4.flush() # 將數據由內存刷入到文件或者硬盤 print(f4.readline()) for line in f4: print(line) # 只在內存中保存一行 f5 = open("test.txt",'rb') print(f5.readline()) f5.close()
r,只讀模式(默認)。
w,只寫模式。【不可讀;不存在則建立;存在則刪除內容;】
a,追加模式。【可讀; 不存在則建立;存在則只追加內容;】
"+" 表示能夠同時讀寫某個文件shell
r+,可讀寫文件。【可讀;可寫;可追加】
w+,寫讀
a+,同a編程
python 2.7中 with open('log','r') as f: for line in f: print(line) python3中: with open('log1') as obj1, open('log2') as obj2: pass
在python2中,默認編碼是ASSIC編碼,若在文件中指定文件的編碼方式爲「utf-8",若想轉化成gbk,須要先解碼爲unicode,轉編碼爲gbkjson
例如:windows
#!/usr/bin/env python #-*- coding:utf-8 -*- #author luotianshuai import chardet tim = '你好' print chardet.detect(tim) #先解碼爲Unicode編碼,而後在從Unicode編碼爲GBK new_tim = tim.decode('UTF-8').encode('GBK') print chardet.detect(new_tim) #結果 ''' {'confidence': 0.75249999999999995, 'encoding': 'utf-8'} {'confidence': 0.35982121203616341, 'encoding': 'TIS-620'}
python3中:服務器
在python3中,默認的就是unicode # author:snate tim =u"你好" new_tim = tim.encode('GBK')直接編碼就能夠。 print(new_tim) new_time=tim.encode("GBK").decode("GBK").encode("GB2312") print(new_tim)
面向對象是把構成問題事務分解成各個對象,創建對象的目的不是爲了完成一個步驟,而是爲了描敘某個事物在整個解決問題的步驟中的行爲。
面向過程就是分析出解決問題所須要的步驟,而後用函數把這些步驟一步一步實現,使用的時候一個一個依次調用就能夠了。
簡單說,"函數式編程"是一種"編程範式"(programming paradigm),也就是如何編寫程序的方法論。
它屬於"結構化編程"的一種,主要思想是把運算過程儘可能寫成一系列嵌套的函數調用數據結構
定義: 函數是指將一組語句的集合經過一個名字(函數名)封裝起來,要想執行這個函數,只需調用其函數名便可
函數的特徵:
減小重複代碼
使程序變的可擴展
使程序變得易維護
函數的定義:
語法:
def function(): print("in the function")
還能夠傳遞參數:
def Sum(x,y): sum = x +y return sum
形參變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。所以,形參只在函數內部有效。函數調用結束返回主調用函數後則不能再使用該形參變量
實參能夠是常量、變量、表達式、函數等,不管實參是何種類型的量,在進行函數調用時,它們都必須有肯定的值,以便把這些值傳送給形參。所以應預先用賦值,輸入等辦法使參數得到肯定值。
位置參數和關鍵字參數、默認參數、可變參數
#!/usr/bin/env python # _*_ encoding:utf-8 _*_ # author:snate # 位置參數和關鍵字參數 def test(x,y,z): print(x,y,z) # 默認參數 def test2(sex,name="alex",age=12): print(sex,name,age) # 參數個數不固定的形式參數 def test3(name,*args): print(name,args) def test4(name,**kwargs): print(name,kwargs) test(1,2,3) # 位置參數:實參和形參必須一一對應 test(x=1,y=2,z=2) test(x=1,z=2,y=2) # 關鍵字參數與位置無關,沒必要一一對應 test2("女",age=25,name=12) # 默認參數必須放到後面, test3("gxw",1,1,23,4,["nihao",2,3,5]) #*args 會把多傳入的多個參數變成一個元組形式 test3("gxw",*[1,2,3,4,5]) # *args 會把多傳入的參數變成一個元組形式 test4(name="alex",age=12,sex="f",id=1) # *kwargs 會把多傳入的關鍵字參數變成一個dict形式 ''' 1 2 3 1 2 2 1 2 2 女 12 25 gxw (1, 1, 23, 4, ['nihao', 2, 3, 5]) gxw (1, 2, 3, 4, 5) alex {'id': 1, 'sex': 'f', 'age': 12} '''
在子程序中定義的變量稱爲局部變量,在程序的一開始定義的變量稱爲全局變量。
全局變量做用域是整個程序,局部變量做用域是定義該變量的子程序。
當全局變量與局部變量同名時:
在定義局部變量的子程序內,局部變量起做用;在其它地方全局變量起做用
#!/usr/bin/env python # _*_ encoding:utf-8 _*_ # author:snate school = "oldboy Edu." name = "alec" def test1(name): print("修改前:"+name) name = "alex" print("修改後:"+name) global school school = "MaGe" print(school) test1(name) print(school)
備註:爲了在函數中修改全局變量的值,須要global聲明,可是在之後的工做中禁用。
在函數內部,能夠調用其餘函數。若是一個函數在內部調用自身自己,這個函數就是遞歸函數
def calc(n): print(n) if int(n/2) ==0: return n return calc(int(n/2)) calc(10) ''' 10 5 2 1 '''
遞歸的特徵:
遞歸特徵:
1. 必須有一個明確的結束條件
2. 每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減小
3. 遞歸效率不高,遞歸層次過多會致使棧溢出(在計算機中,函數調用是經過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。因爲棧的大小不是無限的,因此,遞歸調用的次數過多,會致使棧溢出)
變量能夠指向函數,函數的參數能接收變量,那麼一個函數就能夠接收另外一個函數做爲參數,這種函數就稱之爲高階函數
def add(x,y,f): return f(x) + f(y) res = add(3,-6,abs) print(res)
做業1:用python實現簡答的sed替換功能
ReadMe:
這個一個使用python實現簡單sed功能的程序 我的介紹 name:Gaoxuewu nickName:snate blog_addr: http://www.cnblogs.com/itlinux/p/5749369.html 項目需求 利用python實現shell中的sed的簡單替換功能 功能介紹 將文件打開,一行一行的讀,判斷每行中,是否存在要替換的字符,若存在就替換 將替換後的行寫入到新的文件;若不存在直接將讀出的行寫入到另外一個文件。 環境依賴 python3.* window/linux os os模塊 sys模塊 目錄結構 testSed ├── __init__.py ├── README.md # 程序介紹 ├── testSed FlowChart # 程序流程圖 ├──yesterday # 須要讀取的文件 ├── yesterday.bak #替換以前,文件的備份 運行說明 在搭建好的python環境中,運行python testshell.py "年少輕狂" "Alex 很狂",就能實現用"Alex 很狂"替換"年少輕狂"的功能。
流程圖:
程序:
#!/usr/bin/env python # _*_ encoding:utf-8 _*_ # author:snate ''' 將yesterday文件中的「年少輕狂」替換成「alex 很狂" ''' from sys import argv import os f1 = open("yesterday", "r", encoding="utf-8") f2 = open("yesterday.bak", "w", encoding="utf-8") for line in f1: if argv[1] in line: #"年少輕狂" line = line.replace(argv[1], argv[2]) # "---》alex 很狂" f2.write(line) f1.close() f2.close() os.rename("yesterday","yesterday-bak") os.rename("yesterday.bak","yesterday")
做業2:查找、修改、增長和刪除proxy的內容
Readme:
# 這個一個關於proxy配置文件增、刪、查的程序 ### 我的介紹 * name:Gaoxuewu * nickName:snate * email:hangtiangazi@163.com * blog_addr:http://www.cnblogs.com/itlinux/p/5749369.html ### 功能介紹 * 查詢時,輸入域名,顯示域名的相關的backend的信息 * 刪除時,輸入域名,可以刪除域名以及配置服務器相關的信息 * 增長時,須要輸入配置信息的字典,字典中包含backend的域名信息,以及包含IP,Maxconn,server的record列表 1.例如:輸入內容爲:修改需輸入內容舉例:{"backend": "test.oldboy.org","record":{"server": "100.1.7.9","weight": 20,"maxconn": 30}} 程序會自動判斷輸入的格式是否正確,若不正確,提示用戶從新輸入,直到輸入正確的格式。 2.根據輸入的內容的backend的域名,判斷域名是否不在,不存在,添加域名,和須要配置的服務器信息; 3.若域名存在,判斷域名的服務器信息是否存在,若不在提供用戶信息已存在,不須要修改文件;若不存在, 在域名信息後面增長該信息。 ### 環境依賴: * python3以上版本 * linux/windows os * sys 模塊 * os 模塊 * time模塊 ###目錄結構: testProxy ├── __init__.py ├── README.md # 程序介紹 ├── testProxy FlowChart # 程序流程圖 ├──proxy # proxy 配置文件 ├── proxy.bak_.... proxy的備份文件 ├── proxy.log # 日誌文件 ├── tetsProxy.py # 程序 ├──search_backend(search_domain_name) # 查找域名信息 ├──input_format(add_domain_info_str) # 判斷輸入域名及服務器的配置信息是否正確 ├──add_backend() # 添加域名信息 ├──dek_backend(del_domain_name) # 刪除域名相關信息 ├──main() #主程序 ### 運行說明 在搭建好的python環境中,運行python testProxy.py 便可。
程序流程圖:
程序:
#!/usr/bin/env python # _*_ encoding:utf-8 _*_ # author:snate # 經過域名查詢proxy的函數 import json import time import os time_fort1 = "%Y-%m-%d %H:%M:%S" time_fort2 = "%Y-%m-%d-%H-%M-%S" current_time = time.strftime(time_fort1) bak_time = time.strftime(time_fort2) # 查找函數,根據輸入的域名,返回域名的詳細信息 def search_backend(search_domain_name): ''' :param : Domain name :return: the specific information of Daomain ,Fomat:list ''' f = open("proxy",'r',encoding="utf-8") info_list=[] Flag = 0 # 設置標誌位 默認值爲0 表示爲匹配 for line in f: line = line.strip() # 去掉兩端的空格和換行 if line == "backend %s" % search_domain_name: Flag = 1 # 若匹配上默認值爲1 elif line.startswith("backend"): Flag = 0 elif Flag == 1 and len(line) != 0: # 接着循環,將doamain的信息保存到info_list中。 info_list.append(line) f.close() return info_list # 判斷輸入的的域名信息及服務器的配置信息是否正確 def input_format(add_domain_info_str): ''' :param add_domain_info_str: :return: boolean ''' add_domain_content = json.loads(add_domain_info_str) try: add_domain_name = add_domain_content["backend"] add_domain_server = add_domain_content["record"]["server"] add_domain_weight = add_domain_content["record"]["weight"] add_domain_maxconn = add_domain_content["record"]["maxconn"] except: return False else: return True # 添加域名信息 def add_backend(): ''' :return: None ''' while True: add_domain_info_str = input("請輸入用戶要增長的配置信息:") Fort_Flag = input_format(add_domain_info_str) if Fort_Flag : add_domain_content = json.loads(add_domain_info_str) add_domain_name = add_domain_content["backend"] add_domain_server = add_domain_content["record"]["server"] add_domain_weight = add_domain_content["record"]["weight"] add_domain_maxconn = add_domain_content["record"]["maxconn"] add_domain_server_info = "server %s %s weight %s maxconn %s "%(add_domain_server,add_domain_server,\ add_domain_weight,add_domain_maxconn) info_list = search_backend(add_domain_name) if len(info_list) == 0: with open("proxy","r",encoding="utf-8") as proxy_read, \ open("new_proxy","w",encoding="utf-8") as proxy_bak_write: content_list = proxy_read.readlines() content_list.append("\n") content_list.append("backend %s\n" %add_domain_name) content_list.append("%s %s" % (8*" ", add_domain_server_info)) proxy_bak_write.writelines(content_list) # 提示用戶沒有域名信息,將配置信息添加到配置文件最後 print("No domain name,We will add to the end of the proxy!") time.sleep(1) print('''\033[31;1mInformation has been added successly!!!!\033[0m''') os.rename("proxy","proxy.bak_%s" % bak_time) os.rename("new_proxy", "proxy") with open("proxy.log", 'a+',encoding='utf-8') as log_write: log_write.write("%s ad d the %s into proxy config successfully!\n" %(current_time,add_domain_server_info)) else: if add_domain_server_info in info_list: # 若服務器信息重疊,提示用戶信息重疊,不須要配置文件 print("\033[31;1mServer_info:%s is existed!,don't need add!!!!\033[0m" % add_domain_server_info) else: info_list.append(add_domain_server_info) with open("proxy", 'r', encoding='utf-8') as proxy_read, \ open("proxy_bak", 'w', encoding='utf-8') as proxy_bak_write: begin_Flag = 0 # 設置獲取目標內容的flag標誌 end_Flag = 0 # 設置限制目標內容循環的標誌 for line in proxy_read.readlines(): if line.strip() == "backend %s" % add_domain_name: # 若其中一行的內容爲「backend domain_name",更改獲取內容表示符的值爲1 begin_Flag = 1 # 更改獲取表示符以後,繼續循環表示列表,若碰到以「backend」開頭的行,從新將開始標誌位設置爲0 elif line.strip().startswith("backend"): begin_Flag = 0 if begin_Flag == 0: # 若獲取內容的表示符爲0 表示非目標內容,直接寫入到proxy_bak文件。 proxy_bak_write.writelines(line); elif begin_Flag == 1 and end_Flag == 0: proxy_bak_write.write("backend %s\n" % add_domain_name) for index,domain_info in enumerate(info_list): info_list[index] == '%s%s\n'%(8*" ",domain_info) proxy_bak_write.writelines(info_list) proxy_bak_write.write('\n') # 最後加一個空白行 end_Flag = 1 # 設置限制目標內容表示符爲1 os.rename("proxy", "proxy.bak_%s" % bak_time) os.rename("proxy_bak", "proxy") with open("proxy.log", "a+",encoding='utf-8') as log_write: log_write.write("%s add the %s into %s proxy config\n" % (current_time, add_domain_server_info,\ add_domain_name)) break else: print("您輸入的格式不正確,請從新輸入!") # 刪除域名信息 def del_backend(del_domain_name): ''' :param del_domain_name: :return: None ''' with open("proxy", 'r', encoding='utf-8') as proxy_read, \ open("proxy_bak", 'w',encoding='utf-8') as proxy_bak_write: begin_Flag = 0 for line in proxy_read.readlines(): line = line.strip() if "backend %s" %del_domain_name == line: begin_Flag == 1 elif line.startswith("backend"): begin_Flag = 1 if begin_Flag == 0 : proxy_bak_write.write(line) with open("proxy.log",'a+',encoding='utf-8') as log_write: log_write.write("%s del the %s info!\n"% (current_time, del_domain_name)) os.rename("proxy","proxy.bak_%s" %(bak_time)) os.rename("proxy.bak","proxy") print("%s's info is successfully deleted!" % del_domain_name) # 主程序 def main(): ''' :return: none ''' while True: print(''' 1.查詢 2.增長 3.刪除 4.退出 ''') user_choose = input("請輸入您的選擇:") if user_choose.isdigit(): user_choose = int(user_choose) if user_choose == 1: search_domain_name = input("請輸入您要查詢詳細的域名:") info_list = search_backend(search_domain_name) if len(info_list) == 0: print("The info of %s don't exist" % search_domain_name) else: for line in info_list: print('\033[31;1m%s\033[0m' % line) elif user_choose == 2: add_backend() elif user_choose == 3: del_domain_name = input("input the domain name you want to delete:") info_list = search_backend(del_domain_name) if len(info_list) == 0: print("要刪除的域名信息不存在,不執行任何操做!") else: del_backend(del_domain_name) elif user_choose == 4: for i in range(3): print("程序在\033[31;1m[%s]\033[0m秒後退出!" % (3-i)) time.sleep(1) exit() else: print("您的輸入有誤,請從新輸入:") main()