模塊分類: 好處: 標準庫: help("modules") 查看全部python自帶模塊列表 第三方開源模塊: 自定義模塊: 模塊調用: import module from os import rmdir from module.xx.xx import xx as rename from module.xx import * (不推薦) 注意: 模塊一旦被調用,就至關於執行了另爲一個py文件裏的代碼。 自定義模塊: 查找模塊路徑依據:當前目錄範圍、sys.path ---> 只在當前程序裏有效 site-packages: 全部的標準庫,包括第三方 和 自帶模塊。 依次去查找module 開源模塊安裝、使用: https://pypi.python.org/pypi 是python的開元模塊庫。 pip install PyTrion 怎麼去配置國內的豆瓣源。 包(Package)及跨模塊導入: 包: 一個文件夾管理多個模塊文件,這個文件夾就成爲包。 crm proj manage.py 都在同一級別下 從當前路徑下尋找,想在manage.py裏導入views.py ---> from crm import views python2: 包就是文件夾,但該文件夾下必須存在 __init__.py 文件, 該文件的內容能夠爲空。 __int__.py用於標識當前文件夾是一個包。 python3: 在python3裏,即便目錄下沒__int__.py文件也能建立成功, 猜應該是解釋器優化所致,但建立包仍是要記得加上這個文件. 跨模塊的導入: 爲何crm包裏的views.py想導入proj包裏的settings.py ---> sit-packages 列表打印的第一個值是''。 ''表明着總入口程序manage.py所在的路徑 而不是執行views.py 的路徑。只有入口的程序的路徑會加入到sit-packages裏, 而裏面間接的調用無論多少層和views.py 不要緊。 只要manage.py的路徑在sie-packages裏,只能是from proj import setting。 跨模塊導入2: 問題一: 把views.py做爲入口文件,在views.py裏導入proj文件裏的settings.py ---> import os,sys # sys.path.append("……/my_proj/") # print(dir()) # print(__file__) ---> 在pycharm裏打印的是絕對路徑,但在命令行裏打印相對路徑 # print(os.path.abspath(__file__)) ---> 就是真正的獲取 絕對路徑 # os.path.dirname() 的做用是 在絕對路徑的基礎上 返到上一層。 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from proj import settings "出手就是專業的" 程序在哪執行,當前路徑就是那個。要想導入其餘模塊,就要找到那個模塊的路徑。 相對導入: 問題一: 在入口manages.py裏導入在crm文件夾裏的views.py, 在views.py裏導入models --->在views.py裏: import models # 錯誤,緣由: 由於當前路徑是manages.py的所在路徑,沒有models.py, 而且sit-packages裏也沒有。不要認爲views與models同級別就能夠! from crm import models # 正確寫法 from . import models # 正確寫法, . 表明相對導入 from ..proj import settings -> SystemError: Parent module '' not loaded, cannot perform relative import -> 或 ValueError: attempted relative import beyond top-level package 這兩個錯誤的緣由歸根結底是同樣的:在涉及到相對導入時,package所對應的文件夾必須正確的被python解釋器視做package, 而不是普通文件夾。不然因爲不被視做package,沒法利用package之間的嵌套關係實現python中包的相對導入。 文件夾被python解釋器視做package須要知足兩個條件: 1、文件夾中必須有__init__.py文件,該文件能夠爲空,但必須存在該文件。 2、不能做爲頂層模塊來執行該文件夾中的py文件(即不能做爲主函數的入口)。 time模塊詳解: time.time(): 當前時間戳, 從1970.2.1 8:00年到如今 time.localtime(): 本地時間 (是操做系統的時間) time.gmtime(): 將一個時間戳轉換爲UTC時區(0時區)的struct_time。 time.mktime(): 將一個struct_time轉化爲時間戳。 time.sleep(): 推遲執行時間 time.asctime(): 形式:'Sun Oct 1 12:04:38 2017' time.ctime(): time.strftime('%Y-%m-%d %H:%M:%S %A', 時間對象): time.strptime(): datetime模塊詳解: datetime.date: 表示日期的類。經常使用的屬性有year, month, day; datetime.time: 表示時間的類。經常使用的屬性有hour, minute, second, microsecond; datetime.datetime.now(): 返回當前的datetime日期類型 datetime.date.fromtimestamp(time.time()): 把一個時間戳轉爲datetime日期類型 datetime.datetime: 表示日期時間。 datetime.timedelta: 表示時間間隔,即兩個時間點之間的長度。 時間運算: >>> datetime.datetime.now() datetime.datetime(2018, 5, 8, 15, 55, 8, 864325) >>> datetime.datetime.now() + datetime.timedelta(4) #當前時間 +4天 datetime.datetime(2018, 5, 12, 15, 55, 33, 643242) >>> datetime.datetime.now() + datetime.timedelta(hours=4) #當前時間+4小時 datetime.datetime(2018, 5, 8, 19, 55, 53, 93034) 時間替換: >>> d = datetime.datetime.now() >>> d.replace(year=2999,month=11,day=30) datetime.date(2999, 11, 30) random模塊: random.randint(1,100): 1-100之間的隨機數,包含100 random.randrange(1,100): 1-100之間的隨機數,不包含100 random.choice('assxds$#%ds'): 返回一個給定數據集合中的隨機字符 random.sample('abcdefghi',3): 從多個字符中選取特定數量的字符['a', 'd', 'b'] random.random(): 返回一個隨機浮點數 生成隨機字符串: 隨機驗證碼 >>> import string >>> ''.join(random.sample(string.ascii_lowercase + string.digits, 6)) '4fvda1' >>> string.digits '0123456789' >>> string.ascii_letters 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> string.hexdigits '0123456789abcdefABCDEF' >>> string.octdigits '01234567' >>> string.ascii_lowercase 'abcdefghijklmnopqrstuvwxyz' >>> string.ascii_uppercase 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' >>>string.punctuation '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' 洗牌: >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> random.shuffle(a) >>> a [3, 0, 7, 2, 1, 6, 5, 8, 9, 4] os模塊: 獲得當前工做目錄,即當前Python解釋器 腳本工做的目錄路徑: os.getcwd() 返回指定目錄下的全部文件和目錄名:os.listdir() 函數用來刪除一個文件:os.remove() 刪除多個目錄:os.removedirs(r「c:\python」) 檢驗給出的路徑是不是一個文件:os.path.isfile() 檢驗給出的路徑是不是一個目錄:os.path.isdir() 判斷是不是絕對路徑:os.path.isabs() 檢驗給出的路徑是否真地存:os.path.exists() 返回一個路徑的目錄名和文件名:os.path.split() e.g os.path.split('/home/swaroop/byte/code/poem.txt') 結果:('/home/swaroop/byte/code', 'poem.txt') 分離擴展名:os.path.splitext() e.g os.path.splitext('/usr/local/test.py') 結果:('/usr/local/test', '.py') 獲取路徑名:os.path.dirname() 得到絕對路徑: os.path.abspath() 獲取文件名:os.path.basename() 運行shell命令: os.system() 讀取操做系統環境變量HOME的值:os.getenv("HOME") 返回操做系統全部的環境變量: os.environ 設置系統環境變量,僅程序運行時有效:os.environ.setdefault('HOME','/home/alex') 給出當前平臺使用的行終止符:os.linesep Windows使用'\r\n',Linux and MAC使用'\n' 指示你正在使用的平臺:os.name 對於Windows,它是'nt',而對於Linux/Unix用戶,它是'posix' 重命名:os.rename(old, new) 建立多級目錄:os.makedirs(r「c:\python\test」) 建立單個目錄:os.mkdir(「test」) 獲取文件屬性:os.stat(file) 修改文件權限與時間戳:os.chmod(file) 獲取文件大小:os.path.getsize(filename) 結合目錄名與文件名:os.path.join(dir,filename) 改變工做目錄到dirname: os.chdir(dirname) 獲取當前終端的大小: os.get_terminal_size() 殺死進程: os.kill(10884,signal.SIGKILL) sys模塊: shutil模塊: 高級的 文件、文件夾、壓縮包 處理模塊. shutil.copyfileobj(fsrc, fdst[, length]):將文件內容拷貝到另外一個文件中. shutil.copyfile(src, dst): 拷貝文件. shutil.copymode(src, dst): 僅拷貝權限。內容、組、用戶均不變. shutil.copystat(src, dst): 僅拷貝狀態的信息,包括:mode bits, atime, mtime, flags shutil.copy(src, dst): 拷貝文件和權限. shutil.copy2(src, dst): 拷貝文件和狀態信息. shutil.ignore_patterns(*patterns) shutil.copytree(src, dst, symlinks=False, ignore=None): 遞歸的去拷貝文件夾 shutil.rmtree(path[, ignore_errors[, onerror]]): 遞歸的去刪除文件 shutil.move(src, dst): 遞歸的去移動文件,它相似mv命令,其實就是重命名。 shutil.make_archive(base_name, format,...): 建立壓縮包並返回文件路徑,例如:zip、tar 建立壓縮包並返回文件路徑,例如:zip、tar base_name: 壓縮包的文件名,也能夠是壓縮包的路徑。只是文件名時,則保存至當前目錄,不然保存至指定路徑, 序列化模塊: json & pickle 序列化是指把內存裏的數據類型轉變成字符串, 以使其能存儲到硬盤或經過網絡傳輸到遠程,由於硬盤或網絡傳輸時只能接受bytes json模塊: import json ① d = json.dumps(data) # 把data變成字符串 f = open("test.json", 'w', encoding='utf-8') f.write(d) f.close() ② f = open("test.json", "w") json.dump(data, f) # 轉成字符串, 並寫入文件裏 或 json.dump(data,open("test.json", "w")) ③ d = json.dumps(data) # 僅把data變成字符串.(如今狀態僅存在內存裏) d2 = json.loads(d) # 從序列化中讀出來 ④ f = open("test.json", "r") json.load(f) 只是把數據類型轉換成字符串存到內存裏的意義? json.dumps() json.loads() 1、把你的內存數據 經過網絡 共享給遠程其餘人. 2、定義了不一樣語言的之間的交互規則(跨平臺、體積小) 注意: dumps只能進行一次, loads屢次會出錯! json序列化的數據類型 只能支持int\str\list\tuple\dict pickle模塊: import pickle 與 json 模塊用法相同, dumps、dump、loads、load d = {'name': 'hyp', 'age': 22} pk = open("data.pkl", "wb") # print(pickle.dumps(d)) # 結果: b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00hypq\x02X\x03\x00\x00\x00ageq\x03K\x16u.' pickle.dump(d, pk) f = open("data.pkl", "rb") d = pickle.load(f) print(d) 注意: 優勢:專爲python設計,支持python全部的數據類型 缺點: 缺點:只能在python中使用,存儲數據佔空間大 序列化shelve模塊: import shelve shelve模塊是一個簡單的k,v將內存數據經過文件持久化的模塊, 能夠持久化任何pickle可支持的python數據格式 能夠修改,但只能是以給key從新賦值的方式改。 能夠添加,刪除 xml處理模塊: <>節點 xml是實現不一樣語言或程序之間進行數據交換的協議,跟json差很少, 但json使用起來更簡單,不過,古時候,在json還沒誕生的黑暗年代, 你們只能選擇用xml呀,至今不少傳統公司如金融行業的不少系統的接口還主要是xml。 import xml.etree.ElementTree as ET tree = ET.parse("xml test") # open root = tree.getroot() # 至關於 f.seek(0) print(root.tag) # 打印標籤: data # 遍歷xml文檔 for child in root: # 循環每個<country> print(child.tag, child.attrib) # child.tag -> country, child.attrib ->字典結構的數據 for i in child: # 循環每個country下的結構 print(i.tag, i.text) # 只遍歷year 節點 for node in root.iter('year'): print(node.tag, node.text) # 修改和刪除xml文檔內容 for node in root.iter('year'): new_year = int(node.text) + 1 node.text = str(new_year) node.set("updated", "yes") # 存儲屬性,存到country的後面 tree.write("xml test") #刪除node for country in root.findall('country'): # 查找全部的country節點 rank = int(country.find('rank').text) # 找到全部rank的值 if rank > 50: root.remove(country) # 刪掉rank>50的country tree.write('output.xml') # 本身建立xml文檔 import xml.etree.ElementTree as ET # 根(root)是namelist root = ET.Element("namelist") # 建立子節點name 和 對應的屬性attrib name = ET.SubElement(root, "name", attrib={"enrolled":"yes"}) # 在name節點下放的參數age,sex, age = ET.SubElement(name, "age", attrib={"checked":"no"}) sex = ET.SubElement(name, "sex") sex.text = 'male' # 給sex賦值 # 第二個節點: name2 name2 = ET.SubElement(root, "name", attrib={"enrolled":"no"}) age = ET.SubElement(name2, "age") age.text = '19' # 給age賦值 et = ET.ElementTree(root) # 生成文檔對象 # xml_declaration ---> 版本號聲明 et.write("build_out.xml", encoding="utf-8", xml_declaration=True) ET.dump(root) #打印生成的格式 configparser模塊: 此模塊用於生成和修改常見配置文檔 [DEFAULT]裏默認存儲每個節點裏都要有的默認值 解析配置文件: >>> import configparser # 導入模塊 >>> config = configparser.ConfigParser() # 實例化(生成對象) >>> config.sections() # 調用sections方法 [] >>> config.read('config.ini') # 讀配置文件(注意文件路徑) ['config.ini'] >>> config.sections() # 調用sections方法(默認不會讀取default) ['bitbucket.org', 'topsecret.server.com'] # 會默認打印DEFAULT下的 for k, v in conf["bitbucket.org"].items(): print(k, v) >>> 'bitbucket.org' in config # 判斷元素是否在sections列表內 True >>> 'bytebong.com' in config False >>> config['bitbucket.org']['User'] # 經過字典的形式取值 'hg' >>> config['DEFAULT']['Compression'] # 'yes' >>> topsecret = config['topsecret.server.com'] >>> topsecret['ForwardX11'] 'no' >>> topsecret['Port'] '50022' >>> for key in config['bitbucket.org']: print(key) # for循環 bitbucket.org 字典的key ... user compressionlevel serveraliveinterval compression forwardx11 >>> config['bitbucket.org']['ForwardX11'] 'yes' 其它增刪改查語法: hashlib加密模塊: subprocess模塊: run() call() Popen() logging模塊: logging的日誌能夠分爲: debug(), info(), warning(), error() and critical()5個級別. 調試 記錄 潛在問題 出問題 嚴重問題 StreamHandler、FileHandler設置的日誌級別要 高於 全局設置的日誌級別, 不然不起做用! (全局的日誌級別默認是 warning) re模塊: 軟件開發目錄規範:
在計算機程序的開發過程當中,隨着程序代碼越寫越多,在一個文件裏代碼就會愈來愈長,愈來愈不容易維護。css
爲了編寫可維護的代碼,咱們把不少函數分組,分別放到不一樣的文件裏,這樣,每一個文件包含的代碼就相對較少,不少編程語言都採用這種組織代碼的方式。在Python中,一個.py文件就稱之爲一個模塊(Module)。html
一、最大的好處是大大提升了代碼的可維護性。其次,編寫代碼沒必要從零開始。當一個模塊編寫完畢,就能夠被其餘地方引用。咱們在編寫程序的時候,也常常引用其餘模塊,包括Python內置的模塊和來自第三方的模塊。node
二、使用模塊還能夠避免函數名和變量名衝突。每一個模塊有獨立的命名空間,所以相同名字的函數和變量徹底能夠分別存在不一樣的模塊中,因此,咱們本身在編寫模塊時,沒必要考慮名字會與其餘模塊衝突。python
分爲三種:git
①內置標準模塊(又稱爲 標準庫),執行hel('modules')查看全部python自帶模塊列表。正則表達式
②第三方開源模塊,能夠經過 pip install 模塊名 聯網安裝。shell
③自定義模塊數據庫
import module from module import xx from module.xx.xx import xx as rename from module.xx.xx import *
注意:模塊一旦被調用,即至關於執行了另一個py文件裏的代碼。編程
這個最簡單, 建立一個.py文件,就能夠稱之爲模塊,就能夠在另一個程序裏導入。json
import sys print(sys.path)
注意:列表第一個元素爲空,即表明當前目錄,因此你本身定義的模塊在當前目錄會被優先導入。
當模塊文件愈來愈多,就須要對模塊文件進行劃分,好比把負責跟數據庫交互的都放一個文件夾,把與頁面交互相關的放一個文件夾。
└── my_proj ├── crm #代碼目錄 │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ └── views.py ├── manage.py └── my_proj #配置文件目錄 ├── settings.py ├── urls.py └── wsgi.py
一個文件夾管理多個模塊文件,這個文件夾就被稱爲 包 。
包就是文件夾,但該文件夾下必須存在 __init__.py 文件, 該文件的內容能夠爲空。__int__.py用於標識當前文件夾是一個包。
注意:在python3裏,即便目錄下沒__int__.py文件也能建立成功,猜應該是解釋器優化所致,但建立包仍是要記得加上這個文件 吧。
from crm import views
目錄結構以下
. ├── __init__.py ├── crm │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ ├── views.py ├── manage.py └── proj ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
根據上面的結構,如何實如今crm/views.py
裏導入proj/settings.py
模塊?
直接導入的話,會報錯,說找到不模塊。因此須要 添加環境變量,把父親級的路徑添加到sys.path中,就能夠了,這樣導入 就至關於從父親級開始找模塊了。
import sys ,os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #__file__的是打印當前被執行的模塊.py文件相對路徑,注意是相對路徑 print(BASE_DIR) sys.path.append(BASE_DIR) from proj import settings def sayhi(): print('hello world!') print(settings.DATABASES)
. ├── __init__.py ├── crm │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ ├── views.py #from ..proj import settings ├── manage.py └── proj ├── __init__.py ├── settings.py #from .import urls ├── urls.py └── wsgi.py
views.py裏代碼
from ..proj import settings def sayhi(): print('hello world!') print(settings.DATABASES)
執行結果報錯了
Traceback (most recent call last): File "my_proj/crm/views.py", line 4, in <module> from ..proj import settings SystemError: Parent module '' not loaded, cannot perform relative import
或者有人會看到這個錯
ValueError: attempted relative import beyond top-level package
其實這兩個錯誤的緣由歸根結底是同樣的:在涉及到相對導入時,package所對應的文件夾必須正確的被python解釋器視做package,而不是普通文件夾。不然因爲不被視做package,沒法利用package之間的嵌套關係實現python中包的相對導入。
文件夾被python解釋器視做package須要知足兩個條件:
一、文件夾中必須有__init__.py文件,該文件能夠爲空,但必須存在該文件。 二、不能做爲頂層模塊來執行該文件夾中的py文件(即不能做爲主函數的入口)。
正確的代碼目錄結構以下:
packages/ ├── __init__.py ├── manage.py #from my_proj.crm import views └── my_proj ├── crm │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ ├── views.py #from . import models; from ..proj import settings └── proj ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
注:雖然python支持相對導入,但對模塊間的路徑關係要求比較嚴格,處理不當就容易出錯,so並不建議在項目裏常用。
一般表示時間的方式:
一、時間戳
二、格式化的時間字符串
三、元組(struct_time)
時間戳(timestamp)的方式:從 1970年1 月1日00:00:00 開始按秒計算。
元組的方式:一共有9個元素。
索引(Index) 屬性(Attribute) 值(Values) 0 tm_year(年) 好比2011 1 tm_mon(月) 1 - 12 2 tm_mday(日) 1 - 31 3 tm_hour(時) 0 - 23 4 tm_min(分) 0 - 59 5 tm_sec(秒) 0 - 61 6 tm_wday(weekday) 0 - 6(0表示週日) 7 tm_yday(一年中的第幾天) 1 - 366 8 tm_isdst(是不是夏令時) 默認爲-1
一、time.localtime():將一個時間戳轉換爲當前時區的元組(struct_time)。
二、time.gmtime() :和 localtime()方法相似,gtime()方法是將一個時間戳轉換爲 UTC 時區(0時區)的struct_time。
三、time.time():返回當前時間的時間戳。
四、time.mktime(t):將一個struct_time轉換爲時間戳。
五、time.sleep():線程推遲指定的時間運行(單位爲 秒)。
六、time.asctime():把一個表示時間的元組或者struct_time表示爲這種形式:'Sun Oct 1 12:04:38 2017'。若是沒有參數,將會將time.localtime()做爲參數傳入。
七、time.ctime():把一個時間戳轉換爲time.asctime()的形式。若是不傳參數,就會以 time.time() 爲默認參數。它的做用至關於time.asctime(time.localtime(secs))。
八、time.strftime(format[, t]):把一個表明時間的元組或struct_time轉換爲格式化的時間字符串。若是 t 未指定,默認傳入 time.localtime()。
例:time.strftime("%Y-%m-%d %X", time.localtime()) 輸出:'2018-4-10 15:45:20'。
九、time.strptime(string[, format]):把一個格式化時間字符串轉化爲 struct_time。與 strftime 是逆向操做。
一、datetime.date:表示日期的類。經常使用的屬性:year、month、day;
二、datetime.time:表示時間的類。經常使用的屬性:hour、minute、second、microsecond;
三、datetime.datatime:表示的是日期的時間。
四、datetime.timedelta:表示時間間隔,即兩點時間點之間的長度。
方法:
一、d = datetime.datetime.now() 返回當前的datetime日期類型。
d.timestamp(),d.today(), d.year,d.timetuple()等方法能夠調用
二、時間運算
>>> datetime.datetime.now() datetime.datetime(2017, 10, 1, 12, 53, 11, 821218) >>> datetime.datetime.now() + datetime.timedelta(4) #當前時間 +4天 datetime.datetime(2017, 10, 5, 12, 53, 35, 276589) >>> datetime.datetime.now() + datetime.timedelta(hours=4) #當前時間+4小時 datetime.datetime(2017, 10, 1, 16, 53, 42, 876275)
三、時間替換
>>> d.replace(year=2999,month=11,day=30)
datetime.date(2999, 11, 30)
>>> random.randrange(1,10) #返回1-10之間的一個隨機數,不包括10 >>> random.randint(1,10) #返回1-10之間的一個隨機數,包括10 >>> random.randrange(0, 100, 2) #隨機選取0到100間的偶數 >>> random.random() #返回一個隨機浮點數 ,在[0, 1)範圍內。 >>> random.choice('abce3#$@1') #返回一個給定數據集合中的隨機字符 '#' >>> random.sample('abcdefghij',3) #從多個字符中選取特定數量的字符 ['a', 'd', 'b'] #生成隨機字符串 >>> import string >>> ''.join(random.sample(string.ascii_lowercase + string.digits, 6)) '4fvda1' #洗牌 >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> random.shuffle(a) >>> a [3, 0, 7, 2, 1, 6, 5, 8, 9, 4]
獲得當前工做目錄,即當前Python腳本工做的目錄路徑: os.getcwd() 返回指定目錄下的全部文件和目錄名:os.listdir() 函數用來刪除一個文件:os.remove() 刪除多個目錄:os.removedirs(r「c:\python」) 檢驗給出的路徑是不是一個文件:os.path.isfile() 檢驗給出的路徑是不是一個目錄:os.path.isdir() 判斷是不是絕對路徑:os.path.isabs() 檢驗給出的路徑是否真地存:os.path.exists() 返回一個路徑的目錄名和文件名:os.path.split() e.g os.path.split('/home/swaroop/byte/code/poem.txt') 結果:('/home/swaroop/byte/code', 'poem.txt') 分離擴展名:os.path.splitext() e.g os.path.splitext('/usr/local/test.py') 結果:('/usr/local/test', '.py') 獲取路徑名:os.path.dirname() 得到絕對路徑: os.path.abspath() 獲取文件名:os.path.basename() 運行shell命令: os.system() 讀取操做系統環境變量HOME的值:os.getenv("HOME") 返回操做系統全部的環境變量: os.environ 設置系統環境變量,僅程序運行時有效:os.environ.setdefault('HOME','/home/alex') 給出當前平臺使用的行終止符:os.linesep Windows使用'\r\n',Linux and MAC使用'\n' 指示你正在使用的平臺:os.name 對於Windows,它是'nt',而對於Linux/Unix用戶,它是'posix' 重命名:os.rename(old, new) 建立多級目錄:os.makedirs(r「c:\python\test」) 建立單個目錄:os.mkdir(「test」) 獲取文件屬性:os.stat(file) 修改文件權限與時間戳:os.chmod(file) 獲取文件大小:os.path.getsize(filename) 結合目錄名與文件名:os.path.join(dir,filename) 改變工做目錄到dirname: os.chdir(dirname) 獲取當前終端的大小: os.get_terminal_size() 殺死進程: os.kill(10884,signal.SIGKILL)
sys.argv 命令行參數List,第一個元素是程序自己路徑 sys.exit(n) 退出程序,正常退出時exit(0) sys.version 獲取Python解釋程序的版本信息 sys.maxint 最大的Int值 sys.path 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 sys.platform 返回操做系統平臺名稱 sys.stdout.write('please:') #標準輸出 , 引出進度條的例子, 注,在py3上不行,能夠用print代替 val = sys.stdin.readline()[:-1] #標準輸入 sys.getrecursionlimit() #獲取最大遞歸層數 sys.setrecursionlimit(1200) #設置最大遞歸層數 sys.getdefaultencoding() #獲取解釋器默認編碼 sys.getfilesystemencoding #獲取內存數據存到文件裏的默認編碼
高級的文件、文件夾、壓縮包 處理模塊
shutil.copyfile( src, dst) 從源src複製到dst中去。固然前提是目標地址是具有可寫權限。拋出的異常信息爲IOException. 若是當前的dst已存在的話就會被覆蓋掉 shutil.move( src, dst) 移動文件或重命名 shutil.copymode( src, dst) 只是會複製其權限其餘的東西是不會被複制的 shutil.copystat( src, dst) 複製權限、最後訪問時間、最後修改時間 shutil.copy( src, dst) 複製一個文件到一個文件或一個目錄 shutil.copy2( src, dst) 在copy上的基礎上再複製文件最後訪問時間與修改時間也複製過來了,相似於cp –p的東西 shutil.copy2( src, dst) 若是兩個位置的文件系統是同樣的話至關因而rename操做,只是更名;若是是不在相同的文件系統的話就是作move操做 shutil.copytree( olddir, newdir, True/Flase) 把olddir拷貝一份newdir,若是第3個參數是True,則複製目錄時將保持文件夾下的符號鏈接,若是第3個參數是False,則將在複製的目錄下生成物理副原本替代符號鏈接 shutil.rmtree( src ) 遞歸刪除一個目錄以及目錄內的全部內容
將文件內容拷貝到另外一個文件中 ,主要是將url返回的數據複製到jpg文件中,造成一個圖形。
import shutil shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
拷貝文件,將 src 複製 dst 中去。若是當前的dst存在的話就會被覆蓋掉。src和dst必須是文件。
shutil.copyfile('f1.log', 'f2.log') #目標文件無需存在
僅拷貝權限。內容、組、用戶均不變,目標文件須要存在。
shutil.copymode('f1.log', 'f2.log') #目標文件必須存在
僅拷貝文件狀態的信息,包括:mode bits atims mtime flags,目標文件必須存在。
shutil.copystat('f1.log', 'f2.log') #目標文件必須存在
拷貝文件和權限。
shutil.copy('f1.log', 'f2.log')
拷貝文件和狀態信息。
遞歸的去拷貝文件夾。
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目標目錄不能存在,注意對folder2目錄父級目錄要有可寫權限,ignore的意思是排除
#ubuntu 默認的可能沒有安裝tree,安裝下便可apt-get install tree # root@tim:/opt# tree 1/ 1/ └── 2 └── 3 └── 4 └── 5 >>> shutil.copytree("1","0") root@tim:/opt# tree 0 └── 2 └── 3 └── 4 └── 5 directories, 0 files
def ignore_patterns(*patterns): """Function that can be used as copytree() ignore parameter. Patterns is a sequence of glob-style patterns that are used to exclude files""" def _ignore_patterns(path, names): ignored_names = [] for pattern in patterns: ignored_names.extend(fnmatch.filter(names, pattern)) return set(ignored_names) return _ignore_patterns def copytree(src, dst, symlinks=False, ignore=None): """Recursively copy a directory tree using copy2(). The destination directory must not already exist. If exception(s) occur, an Error is raised with a list of reasons. If the optional symlinks flag is true, symbolic links in the source tree result in symbolic links in the destination tree; if it is false, the contents of the files pointed to by symbolic links are copied. The optional ignore argument is a callable. If given, it is called with the `src` parameter, which is the directory being visited by copytree(), and `names` which is the list of `src` contents, as returned by os.listdir(): callable(src, names) -> ignored_names Since copytree() is called recursively, the callable will be called once for each directory that is copied. It returns a list of names relative to the `src` directory that should not be copied. XXX Consider this example code rather than the ultimate tool. """ names = os.listdir(src) if ignore is not None: ignored_names = ignore(src, names) else: ignored_names = set() os.makedirs(dst) errors = [] for name in names: if name in ignored_names: continue srcname = os.path.join(src, name) dstname = os.path.join(dst, name) try: if symlinks and os.path.islink(srcname): linkto = os.readlink(srcname) os.symlink(linkto, dstname) elif os.path.isdir(srcname): copytree(srcname, dstname, symlinks, ignore) else: # Will raise a SpecialFileError for unsupported file types copy2(srcname, dstname) # catch the Error from the recursive copytree so that we can # continue with other files except Error, err: errors.extend(err.args[0]) except EnvironmentError, why: errors.append((srcname, dstname, str(why))) try: copystat(src, dst) except OSError, why: if WindowsError is not None and isinstance(why, WindowsError): # Copying file access times may fail on Windows pass else: errors.append((src, dst, str(why))) if errors: raise Error, errors shutil.copytree
遞歸的去刪除文件。
def rmtree(path, ignore_errors=False, onerror=None): """Recursively delete a directory tree. If ignore_errors is set, errors are ignored; otherwise, if onerror is set, it is called to handle the error with arguments (func, path, exc_info) where func is os.listdir, os.remove, or os.rmdir; path is the argument to that function that caused it to fail; and exc_info is a tuple returned by sys.exc_info(). If ignore_errors is false and onerror is None, an exception is raised. """ if ignore_errors: def onerror(*args): pass elif onerror is None: def onerror(*args): raise try: if os.path.islink(path): # symlinks to directories are forbidden, see bug #1669 raise OSError("Cannot call rmtree on a symbolic link") except OSError: onerror(os.path.islink, path, sys.exc_info()) # can't continue even if onerror hook returns return names = [] try: names = os.listdir(path) except os.error, err: onerror(os.listdir, path, sys.exc_info()) for name in names: fullname = os.path.join(path, name) try: mode = os.lstat(fullname).st_mode except os.error: mode = 0 if stat.S_ISDIR(mode): rmtree(fullname, ignore_errors, onerror) else: try: os.remove(fullname) except os.error, err: onerror(os.remove, fullname, sys.exc_info()) try: os.rmdir(path) except os.error: onerror(os.rmdir, path, sys.exc_info()) shutil.rmtree
遞歸的去移動文件,它相似mv命令,其實就是重命名。
建立壓縮包並返回文件路徑,例如:zip、tar建立壓縮包並返回文件路徑,例如:zip、tar
如 data_bak =>保存至當前路徑
如:/tmp/data_bak =>保存至/tmp/
#將 /data 下的文件打包放置當前程序目錄 import shutil ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data') #將 /data下的文件打包放置 /tmp/目錄 import shutil ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
shutil 對壓縮包的處理是調用 ZipFile 和 TarFile 兩個模塊來進行的,詳細:
import zipfile # 壓縮 z = zipfile.ZipFile('laxi.zip', 'w') z.write('a.log') z.write('data.data') z.close() # 解壓 z = zipfile.ZipFile('laxi.zip', 'r') z.extractall(path='.') z.close()
import tarfile # 壓縮 >>> t=tarfile.open('/tmp/egon.tar','w') >>> t.add('/test1/a.py',arcname='a.bak') >>> t.add('/test1/b.py',arcname='b.bak') >>> t.close() # 解壓 >>> t=tarfile.open('/tmp/egon.tar','r') >>> t.extractall('/egon') >>> t.close()
序列化是指把內存裏的數據類型轉變成字符串,以使其能存儲到硬盤或經過網絡傳輸到遠程,由於硬盤或網絡傳輸時只能接受bytes。
用於序列化的兩個模塊:
一、json,用於 字符串 和 Python數據類型 間的轉換。
二、pickle,用於Python特有的類型和Python的數據類型間的轉換。
json模塊 和 pickle模塊 都有四個功能:dumps、dump、loads、load
import pickle data = {'k1':123,'k2':'Hello'} # pickle.dumps 將數據經過特殊的形式轉換位只有python語言認識的字符串 p_str = pickle.dumps(data) print(p_str) #pickle.dump 將數據經過特殊的形式轉換位只有python語言認識的字符串,並寫入文件 with open('D:/result.pk','wb',encoding='utf8') as fp: pickle.dump(data,fp) import json # json.dumps 將數據經過特殊的形式轉換位全部程序語言都認識的字符串 j_str = json.dumps(data) print(j_str) #pickle.dump 將數據經過特殊的形式轉換位只有python語言認識的字符串,並寫入文件 with open('D:/result.json','wb',encoding='utf8') as fp: json.dump(data,fp)
json:跨語言,體積小,但只能 支持 int/str/list/tuple/dict
pickle:專爲Python設計,支持Python全部的數據類型,但只能在Python中使用,存儲數據佔空間大。
xml的格式以下,就是經過<>節點來區別數據結構的:
<?xml version="1.0"?> <data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N"/> </country> <country name="Panama"> <rank updated="yes">69</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data>
xml協議在各個語言裏的都 是支持的,在python中能夠用如下模塊操做xml:
import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() print(root.tag) #遍歷xml文檔 for child in root: print(child.tag, child.attrib) for i in child: print(i.tag,i.text) #只遍歷year 節點 for node in root.iter('year'): print(node.tag,node.text)
修改和刪除xml文檔內容
import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() #修改 for node in root.iter('year'): new_year = int(node.text) + 1 node.text = str(new_year) node.set("updated","yes") tree.write("xmltest.xml") #刪除node for country in root.findall('country'): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write('output.xml')
本身建立xml文檔:
import xml.etree.ElementTree as ET new_xml = ET.Element("namelist") name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"}) age = ET.SubElement(name,"age",attrib={"checked":"no"}) sex = ET.SubElement(name,"sex") sex.text = '33' name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"}) age = ET.SubElement(name2,"age") age.text = '19' et = ET.ElementTree(new_xml) #生成文檔對象 et.write("test.xml", encoding="utf-8",xml_declaration=True) ET.dump(new_xml) #打印生成的格式
好多軟件的常見配置文件格式以下:
[DEFAULT] ServerAliveInterval = 45 Compression = yes CompressionLevel = 9 ForwardX11 = yes [bitbucket.org] User = hg [topsecret.server.com] Port = 50022 ForwardX11 = no ```
解析配置文件
>>> import configparser # 導入模塊 >>> config = configparser.ConfigParser() #實例化(生成對象) >>> config.sections() #調用sections方法 [] >>> config.read('example.ini') # 讀配置文件(注意文件路徑) ['example.ini'] >>> config.sections() #調用sections方法(默認不會讀取default) ['bitbucket.org', 'topsecret.server.com'] >>> 'bitbucket.org' in config #判斷元素是否在sections列表內 True >>> 'bytebong.com' in config False >>> config['bitbucket.org']['User'] # 經過字典的形式取值 'hg' >>> config['DEFAULT']['Compression'] 'yes' >>> topsecret = config['topsecret.server.com'] >>> topsecret['ForwardX11'] 'no' >>> topsecret['Port'] '50022' >>> for key in config['bitbucket.org']: print(key) # for循環 bitbucket.org 字典的key ... user compressionlevel serveraliveinterval compression forwardx11 >>> config['bitbucket.org']['ForwardX11'] 'yes'
其它增刪改查語法
```python [group1] # 支持的兩種分隔符「=」, 「:」 k1 = v1 k2:v2 [group2] k1 = v1 import ConfigParser config = ConfigParser.ConfigParser() config.read('i.cfg') # ########## 讀 ########## #secs = config.sections() #print(secs) #options = config.options('group2') # 獲取指定section的keys #print(options) #item_list = config.items('group2') # 獲取指定 section 的 keys & values ,key value 以元組的形式 #print(item_list) #val = config.get('group1','key') # 獲取指定的key 的value #val = config.getint('group1','key') # ########## 改寫 ########## #sec = config.remove_section('group1') # 刪除section 並返回狀態(true, false) #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")) ```
經常使用的正則表達式規則:
二十個正則表達式: 1.校驗密碼強度 密碼的強度必須是包含大小寫字母和數字的組合,不能使用特殊字符,長度在8-10之間。 ^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$ 2.校驗中文 字符串只能是中文 ^[\\]u4e00-\\u9fa5]{0,}$ 3.由數字、26個英文字母或下劃線組成的字符串 ^\\w+$ 4.校驗E-Mail地址 同密碼同樣,下面是email地址合規性的正則檢查語句 [\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])? 5.校驗身份證號碼 下面是身份證號碼的正則校驗,15或18位。 15位: ^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$ 18位: ^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$ 6.校驗日期 "yyyy-mm-dd" 格式的日期校驗,已考慮平閏年。 ^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$ 7.校驗金額 金額校驗,精確到2位小數 ^[0-9]+.(.[0-9]{2})?$1 8.校驗手機號
下面是國內1三、1五、18開頭的手機號正則表達式。(可根據目前收集號擴展前兩位開頭號碼)
^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9])\\d{8}$ 9.判斷IE版本
^.*MSIE [5-8](?:\\.[0-9]+?(?!.*Trident\\/)[5-9]\\.0).*$ 10.校驗IP-v4地址 11.校驗IP-v4地址 12.檢查URL的前綴
應用開發中不少時候須要區分請求是HTTPS或者是HTTP,經過下面的表達式能夠提取一個url前綴而後再進行邏輯判斷
if (!s.match(/^[a-zA-Z]+:\\/\\//))
{
s = 'http://' + s;
} 13.提取URL連接
下面的表達式能夠篩選處一段文本中的URL。
^(f|ht){1}(tp|tps):\\/\\/([\\w-]+\\.)+[\\w-]+(\\/[\\w- ./?%&=]*)? 14.文件路徑及擴展名校驗
驗證Windows下文件路徑和擴展名(下面是以.txt文件爲例)
^([a-zA-Z]\\:|\\\\)\\\\([^\\\\]+\\\\)*[^\\/:*?"<>|]+\\.txt(1)?$ 15.提取Color Hex Codes
抽取網頁中的顏色的代碼,可使用下面的表達式
^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$ 16.提取網頁圖片
若想提取網頁中全部圖片信息,能夠利用下面的表達式
\\<*[img][^\\\\>]*[src] *= *[\\"\\']{0,1}([^\\"\\'\\ >]*) 17.提取頁面超連接 提取HTML中的超連接 (<a\\s*(?!.*\\brel=)[^>]*)(href="https?:\\/\\/)((?!(?:www\\.)?'/implode('|(?:www\\/)?',$follow_list).'))[^"]+((?!.*\\brel=)[^>]*)(?:[^>]*)>
18.查找css屬性
能夠搜索到相匹配的css屬性
^\\s*[a-zA-Z\\-]+\\s*[:]{1}\\s[a-zA-Z0-9\\s.#]+[;]{1}
19.抽取註釋
若是須要移除html長的註釋,可使用以下表達式
<!--(.*?)-->
20.匹配HTML標籤 能夠匹配出html中的標籤屬性
<\\/?\\w+((\\s+\\w+(\\s*=\\s*(?:".*?"|'.*?'|[\\^'">\\s]+))?)+\\s*)\\/?>
'.' 默認匹配除\n以外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行 '^' 匹配字符開頭,若指定flags MULTILINE,這種也能夠匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) '$' 匹配字符結尾, 若指定flags MULTILINE ,re.search('foo.$','foo1\nfoo2\n',re.MULTILINE).group() 會匹配到foo1 '*' 匹配*號前的字符0次或屢次, re.search('a*','aaaabac') 結果'aaaa' '+' 匹配前一個字符1次或屢次,re.findall("ab+","ab+cd+abb+bba") 結果['ab', 'abb'] '?' 匹配前一個字符1次或0次 ,re.search('b?','alex').group() 匹配b 0次 '{m}' 匹配前一個字符m次 ,re.search('b{3}','alexbbbs').group() 匹配到'bbb' '{n,m}' 匹配前一個字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 結果'abb', 'ab', 'abb'] '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 結果'ABC' '(...)' 分組匹配, re.search("(abc){2}a(123|45)", "abcabca456c").group() 結果爲'abcabca45' '\A' 只從字符開頭匹配,re.search("\Aabc","alexabc") 是匹配不到的,至關於re.match('abc',"alexabc") 或^ '\Z' 匹配字符結尾,同$ '\d' 匹配數字0-9 '\D' 匹配非數字 '\w' 匹配[A-Za-z0-9] '\W' 匹配非[A-Za-z0-9] 's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 結果 '\t' '(?P<name>...)' 分組匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 結果{'province': '3714', 'city': '81', 'birthday': '1993'}
re的匹配語法:
一、re.match 從頭開始匹配
二、re.search 匹配包含
三、re.findall 把全部匹配到的字符放到以列表中的元素返回
四、re.split 以匹配到的字符當作列表的分隔符
五、re.sub 匹配字符並替換
六、re.fullmatch 所有匹配