目錄html
1.產生新的名稱空間 2.以新建的名稱空間爲全局名稱空間,執行文件的代碼 3.拿到一個模塊名spam,指向spam.py產生的名稱空間
1.產生新的名稱空間 2.以新建的名稱空間爲全局名稱空間,執行文件的代碼 3.直接拿到就是spam.py產生的名稱空間中名字 優勢:方便,不用加前綴 缺點:容易跟當前文件的名稱空間衝突 __all__=['money'] #加入spam文件內[ ]內必須是字符串 from spam import * #*表明all
內存---->內置------->sys.pathnode
若倒入的模塊跟執行的py不在一個路徑下,則用sys.path:python
方法1. #sys.path.insert更精準 import sys #sys.path.append(r'/Users/boxfish-edu/PycharmProjects/untitled/d/a') sys.path.insert(0,r'/Users/boxfish-edu/PycharmProjects/untitled/d/a') import aaa print(aaa.name) 方法2. #a.b表示兩層目錄 from a.b import bbb print(bbb.name)
'.' 默認匹配除\n以外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行 '^' 匹配字符開頭,若指定flags MULTILINE,這種也能夠匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) '$' 匹配字符結尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也能夠 '*' 匹配*號前的字符0次或屢次,re.findall("ab*","cabb3abcbbac") 結果爲['abb', 'ab', 'a'] '+' 匹配前一個字符1次或屢次,re.findall("ab+","ab+cd+abb+bba") 結果['ab', 'abb'] '?' 匹配前一個字符1次或0次 '{m}' 匹配前一個字符m次 '{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|456)c", "abcabca456c").group() 結果 abcabca456c '\A' 只從字符開頭匹配,re.search("\Aabc","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.match 從頭開始匹配 re.search 匹配包含 re.findall 把全部匹配到的字符放到以列表中的元素返回 re.splitall 以匹配到的字符當作列表分隔符 re.sub 匹配字符並替換
print(re.findall('a.c','abc1\nn2a\nc3\tad_efa * | - =',re.S)) #加上re.s可使.匹配\n print(re.findall('al(?:e)x\smak(?:e)','alex make love')) #固定語法 不僅僅匹配括號裏的
字符 | 描述 |
---|---|
. | 匹配任意一個字符(除了\n) |
\d \D | 數字/非數字 |
\s \S | 空白/非空白字符 |
\w \W | 單詞字符[a-zA-Z0-9]/非單詞字符 |
\b \B | 單詞邊界,一個\w與\W之間的範圍,順序可逆/非單詞邊界 |
# 匹配字符串abc,.表明b >>> re.match('a.c','abc').group() 'abc'
# 匹配任意一數字 >>> re.match('\d','1').group() '1' # 匹配任意一個非數字 >>> re.match('\D','a').group() 'a'
# 匹配任意一個空白字符 >>> re.match("\s"," ").group() ' ' # 匹配任意一個非空白字符 >>> re.match("\S","1").group() '1' >>> re.match("\S","a").group() 'a'
單詞字符即表明[a-zA-Z0-9]mysql
# 匹配任意一個單詞字符 >>> re.match("\w","a").group() 'a' >>> re.match("\w","1").group() '1' # 匹配任意一個非單詞字符 >>> re.match("\W"," ").group() ' '
字符 | 匹配 |
---|---|
* | 匹配前一個字符0次或者無限次 |
+ | 匹配前一個字符1次或者無限次 |
? | 匹配前一個字符0次或者1次 |
{m}/{m,n} | 匹配前一個字符m次或者N次 |
*?/+?/?? | 匹配模式變爲貪婪模式(儘量少匹配字符) |
字符 | 匹配 |
---|---|
prev? | 0個或1個prev |
prev* | 0個或多個prev,儘量多地匹配 |
prev*? | 0個或多個prev,儘量少地匹配 |
prev+ | 1個或多個prev,儘量多地匹配 |
prev+? | 1個或多個prev,儘量少地匹配 |
prev{m} | m個連續的prev |
prev{m,n} | m到n個連續的prev,儘量多地匹配 |
prev{m,n}? | m到n個連續的prev,儘量少地匹配 |
[abc] | a或b或c |
[^abc] | 非(a或b或c) |
>>> re.match('[A-Z][a-z]*','Aaa').group() 'Aaa' >>> re.match('[A-Z][a-z]*','Aa').group() 'Aa' >>> re.match('[A-Z][a-z]*','A').group() 'A'
# 匹配前一個字符至少一次,若是一次都沒有就會報錯 >>> re.match('[A-Z][a-z]+','A').group() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'group'
>>> re.match('[A-Z][a-z]+','Aa').group() 'Aa' >>> re.match('[A-Z][a-z]+','Aaaaaaa').group() 'Aaaaaaa'
>>> re.match('[A-Z][a-z]?','A').group() 'A' # 只匹配出一個a >>> re.match('[A-Z][a-z]?','Aaaa').group() 'Aa'
#匹配前一個字符至少5次 >>> re.match('\w{5}','asd234').group() 'asd23' # 匹配前面的字符6-10次 >>> re.match('\w{6,10}','asd234').group() 'asd234' # 超過的字符就匹配不出來 >>> re.match('\w{6,10}','asd2313qeadsd4').group() 'asd2313qea'
>>> re.match(r'[0-9][a-z]*','1bc').group() '1bc' # *?匹配0次或者屢次 >>> re.match(r'[0-9][a-z]*?','1bc').group() '1' # +?匹配一次或者屢次,可是隻匹配了一次 >>> re.match(r'[0-9][a-z]+?','1bc').group() '1b' # ??匹配0次或者一次 >>> re.match(r'[0-9][a-z]??','1bc').group() '1'
貪婪匹配和非貪婪匹配web
字符 | 匹配 |
---|---|
^ | 匹配字符串開頭 |
$ | 匹配字符串結尾 |
\A \Z | 指定的字符串必須出如今開頭/結尾 |
# 必須以指定的字符串開頭,結尾必須是@163.com >>> re.match('^[\w]{4,6}@163.com$','asdasd@163.com').group() 'asdasd@163.com'
# 必須以.me結尾 >>> re.match('[\w]{1,20}.me$','ansheng.me').group() 'ansheng.me'
>>> re.match(r'\Awww[\w]*\me','wwwanshengme').group() 'wwwanshengme'
>>> re.match("www|me","www").group() 'www' >>> re.match("www|me","me").group() 'me'
# 匹配163或者126的郵箱 >>> re.match(r'[\w]{4,6}@(163|126).com','asdasd@163.com').group() 'asdasd@163.com' >>> re.match(r'[\w]{4,6}@(163|126).com','asdasd@126.com').group() 'asdasd@126.com'
>>> re.search("(?P<zimu>abc)(?P<shuzi>123)","abc123").groups() ('abc', '123')
>>> res.group("shuzi") '123' >>> res.group("zimu") 'abc'
語法格式:正則表達式
match(pattern, string, flags=0)
釋意:算法
Try to apply the pattern at the start of the string, returning a match object, or None if no match was found.sql
實例:shell
# 從頭開始匹配,匹配成功則返回匹配的對象 >>> re.match("abc","abc123def").group() 'abc' # 從頭開始匹配,若是沒有匹配到對應的字符串就報錯 >>> re.match("\d","abc123def").group() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'group'
語法格式:編程
search(pattern, string, flags=0)
釋意:
Scan through string looking for a match to the pattern, returning a match object, or None if no match was found.
實例:
# 匹配整個字符串,匹配到第一個的時候就返回匹配到的對象 >>> re.search("\d","abc1123def").group() '1'
語法格式:
findall(pattern, string, flags=0)
釋意:
Return a list of all non-overlapping matches in the string.
實例:
# 匹配字符串全部的內容,把匹配到的字符串以列表的形式返回 >>> re.findall("\d","abc123def456") ['1', '2', '3', '4', '5', '6']
語法格式:
split(pattern, string, maxsplit=0)
釋意:
Split the source string by the occurrences of the pattern, returning a list containing the resulting substrings.
實例:
# 指定以數字進行分割,返回的是一個列表對象 >>> re.split("\d+","abc123def4+-*/56") ['abc', 'def', '+-*/', ''] # 以多個字符進行分割 >>> re.split("[\d,]","a,b1c") ['a', 'b', 'c']
語法格式:
sub(pattern, repl, string, count=0)
釋意:
Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable;
if a string, backslash escapes in it are processed. If it is a callable, it's passed the match object and must return a replacement string to be used.
實例:
# 把abc替換成def >>> re.sub("abc","def","abc123abc") 'def123def' # 只替換查找到的第一個字符串 >>> re.sub("abc","def","abc123abc",count=1) 'def123abc'
string方法包含了一百個可打印的ASCII字符,大小寫字母、數字、空格以及標點符號
>>> import string >>> printable = string.printable >>> printable '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
>>> import re # 定義的字符串 >>> source = '''I wish I may, I wish I migth ... Hava a dish of fish tonight.''' # 在字符串中檢索wish >>> re.findall('wish',source) ['wish', 'wish'] # 對源字符串任意位置查詢wish或者fish >>> re.findall('wish|fish',source) ['wish', 'wish', 'fish'] # 從字符串開頭開始匹配wish >>> re.findall('^wish',source) [] # 從字符串開頭匹配I wish >>> re.findall('^I wish',source) ['I wish'] # 從字符串結尾匹配fish >>> re.findall('fish$',source) [] # 從字符串結尾匹配fish tonight. >>> re.findall('fish tonight.$',source) ['fish tonight.'] # 查詢以w或f開頭,後面緊跟着ish的匹配 >>> re.findall('[wf]ish',source) ['wish', 'wish', 'fish'] # 查詢以若干個w\s\h組合的匹配 >>> re.findall('[wsh]+',source) ['w', 'sh', 'w', 'sh', 'h', 'sh', 'sh', 'h'] # 查詢以ght開頭,後面緊跟着一個非數字和字母的匹配 >>> re.findall('ght\W',source) ['ght.'] # 查詢已以I開頭,後面緊跟着wish的匹配 >>> re.findall('I (?=wish)',source) ['I ', 'I '] # 最後查詢以wish結尾,前面爲I的匹配(I出現次數儘可能少) >>> re.findall('(?<=I) wish',source) [' wish', ' wish']
>>> re.match('a','Abc',re.I).group() 'A'
>>> import re >>> pa = re.compile(r'ansheng') >>> pa.match("ansheng.me") <_sre.SRE_Match object; span=(0, 7), match='ansheng'> >>> ma = pa.match("ansheng.me") >>> ma <_sre.SRE_Match object; span=(0, 7), match='ansheng'> # 匹配到的值存到group內 >>> ma.group() 'ansheng' # 返回字符串的全部位置 >>> ma.span() (0, 7) # 匹配的字符串會被放到string中 >>> ma.string 'ansheng.me' # 實例放在re中 >>> ma.re re.compile('ansheng')
import time #時間戳 print(time.time()) #結構化的時間(struct_time):struct_time元組共有9個元素共九個元素:(年,月,日,時,分,秒,一年中第幾周,一年中第幾天,夏令時) print(time.localtime()) #本地時區的struct_time print(time.localtime().tm_year) print(time.gmtime()) #UTC時區的struct_time #格式化字符串 print(time.strftime('%Y-%m-%d %H:%M:%S')) print(time.strftime('%Y-%m-%d %X')) print(time.localtime(123123131)) #將一個時間戳轉換爲當前時區的struct_time print(time.localtime(time.time())) #時間戳->結構化時間 print(time.mktime(time.localtime())) #將一個struct_time轉化爲時間戳。 print(time.strftime('%Y %X',time.localtime())) #結構化時間->格式化字符串時間 print(time.strptime('2017-06-19 10:41:28','%Y-%m-%d %X')) #格式化字符串時間->結構化時間 print(time.ctime(123123132)) print(time.asctime(time.localtime()))
import random print(random.random()) # (0,1)----float 大於0且小於1之間的小數 print(random.randint(1, 3)) # [1,3] 大於等於1且小於等於3之間的整數 print(random.randrange(1, 3)) # [1,3) 大於等於1且小於3之間的整數 print(random.randrange(1, 10,2)) print(random.choice([1, '23', [4, 5]])) # 1或者23或者[4,5] print(random.sample([1, '23', [4, 5]], 2)) # 列表元素任意2個組合 print(random.uniform(1, 3)) # 大於1小於3的小數,如1.927109612082716 item = [1, 3, 5, 7, 9] random.shuffle(item) # 打亂item的順序,至關於"洗牌" print(item)
proxy_ip=[ '1.1.1.1', '1.1.1.2', '1.1.1.3', '1.1.1.4', ] print(random.choice(proxy_ip))
def v_code(n=5): res= '' for i in range(n): a = random.randint(0,9) b = chr(random.randint(65,90)) c = random.choice([a,b]) res +=str(c) return res a = v_code(5) print(a)
os模塊是與操做系統交互的一個接口
os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑 os.chdir("dirname") 改變當前腳本工做目錄;至關於shell下cd os.curdir 返回當前目錄: ('.') os.pardir 獲取當前目錄的父目錄字符串名:('..') os.makedirs('dirname1/dirname2') 可生成多層遞歸目錄 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.environ 獲取系統環境變量 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[, ...]]) 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略 os.path.getatime(path) 返回path所指向的文件或者目錄的最後存取時間 os.path.getmtime(path) 返回path所指向的文件或者目錄的最後修改時間 os.path.getsize(path) 返回path的大小
在Linux和Mac平臺上,該函數會原樣返回path,在windows平臺上會將路徑中全部字符轉換爲小寫,並將全部斜槓轉換爲飯斜槓。 >>> os.path.normcase('c:/windows\\system32\\') 'c:\\windows\\system32\\' 規範化路徑,如..和/ >>> os.path.normpath('c://windows\\System32\\../Temp/') 'c:\\windows\\Temp' >>> a='/Users/jieli/test1/\\\a1/\\\\aa.py/../..' >>> print(os.path.normpath(a)) /Users/jieli/test1
os路徑處理 #方式一:推薦使用 import os #具體應用 import os,sys possible_topdir = os.path.normpath(os.path.join( os.path.abspath(__file__), os.pardir, #上一級 os.pardir, os.pardir )) sys.path.insert(0,possible_topdir) #方式二:不推薦使用 os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.argv 命令行參數List,第一個元素是程序自己路徑 sys.exit(n) 退出程序,正常退出時exit(0) sys.version 獲取Python解釋程序的版本信息 sys.maxint 最大的Int值 sys.path 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 sys.platform 返回操做系統平臺名稱 進度條: import sys,time for i in range(50): sys.stdout.write('%s\r' %('#'*i)) #\r將光標移動到首行 sys.stdout.flush() time.sleep(0.1) ''' 注意:在pycharm中執行無效,請到命令行中以腳本的方式執行 '''
高級的 文件、文件夾、壓縮包 處理模塊
將文件內容拷貝到另外一個文件中
import shutil shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
拷貝文件
shutil.copyfile('f1.log', 'f2.log') #目標文件無需存在
僅拷貝權限。內容、組、用戶均不變
shutil.copymode('f1.log', 'f2.log') #目標文件必須存在
僅拷貝狀態的信息,包括:mode bits, atime, mtime, flags
shutil.copystat('f1.log', 'f2.log') #目標文件必須存在
拷貝文件和權限
import shutil shutil.copy('f1.log', 'f2.log')
拷貝文件和狀態信息
import shutil shutil.copy2('f1.log', 'f2.log')
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() zipfile壓縮解壓縮
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() tarfile壓縮解壓縮
import json #序列化的過程:dic--->res=json.dups(dic)--->f.write(res) dic={ 'name':'alex', 'age':9000, 'height':'150cm', } with open('a.json','w') as f: res = json.dumps(dic) print(res, type(res)) f.write(res) #反序列化的過程:dic =f.read()---> res = json.loads(res)--->dic=res with open('a.json','r') as f: res = f.read() dic = json.loads(res) print(dic,type(dic)) print(dic['name']) #json的便捷操做 json.dump(dic,open('b.json','w')) res = json.load(open('b.json','r')) print(res)
import pickle dic={'name':'alex','age':13} print(pickle.dumps(dic)) with open('a.pkl','wb') as f: f.write(pickle.dumps(dic)) with open('a.pkl','rb') as f: d = pickle.loads(f.read()) print(d,type(d)) pickle.dump(dic,open('b.pkl','wb')) res = pickle.load(open('b.pkl','rb')) print(res) import json import pickle def func(): print('from func') #json.dumps(func)# 報錯,json不支持python的函數類型 f=pickle.dumps(func) print(f) pickle.dump(func,open('c.pkl','wb')) res=pickle.load(open('c.pkl','rb')) print(res) res()
Pickle的問題和全部其餘編程語言特有的序列化問題同樣,就是它只能用於Python,而且可能不一樣版本的Python彼此都不兼容,所以,只能用Pickle保存那些不重要的數據,不能成功地反序列化也不要緊。
shelve模塊比pickle模塊簡單,只有一個open函數,返回相似字典的對象,可讀可寫;key必須爲字符串,而值能夠是python所支持的數據類型
import shelve f=shelve.open(r'sheve.txt') f['student1']={'name':'egon','age':18,'height':'180cm'} print(f['student1']['name']) f.close()
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數據
xml操做:
#!/usr/bin/python # -*- coding:utf-8 -*- import xml.etree.ElementTree as ET tree = ET.parse("a") root = tree.getroot() print(root.iter('year')) #全文搜索 print(root.find('country')) #在root的子節點找,只找一個 print(root.findall('country')) #在root的子節點找,找全部 for country in root: print('=====>',country.attrib['name']) for item in country: print(item.tag,item.text,item.attrib) for year in root.iter('year'): print(year.tag,year.text,year.attrib) #tag,text,attrib 分別描述不一樣的內容 #修改 for year in root.iter('year'): print(year.text) year.text=str(int(year.text)+1) print(year.attrib) year.set('update','yes') tree.write('b.xml') #建立並修改文件 tree.write('a') #更改當前文件 for country in root: print(country) print('===>',country.find('year')) year=country.find('year') if int(year.text) > 2010: country.remove(year) tree.write('d.xml') #增長 for country in root: print(country) # print('===>',country.find('year')) year=country.find('year') if int(year.text) > 2010: year2 = ET.Element('year2') year2.text=str(int(year.text)+1) year2.set('update','yes') country.append(year2) tree.write('e.xml') #本身建立xml文檔: 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) # 打印生成的格式
Python’s interfaces for processing XML are grouped in the xml package.
帶分隔符的文件僅有兩維的數據:行和列。若是你想在程序之間交換數據結構,須要一種方法把層次結構、序列、集合和其餘的結構編碼成文本。
XML
是最突出的處理這種轉換的標記(markup)格式,它使用標籤(tag)分個數據,以下面的實例文件menu.xml所示:
<?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> <title>安生's Blog</title> <subtitle>大好時光!</subtitle> <link href="/atom.xml" rel="self"/> <link href="https://blog.ansheng.me/"/> <updated>2016-05-24T15:29:19.000Z</updated> <id>https://blog.ansheng.me/</id> <author> <name>安生</name> </author> </feed>
<
字符開頭,例如實例中的feed、title、subtitle、author。thing
的標籤內沒有內容或者子標籤,那麼它能夠用在右尖括號的前面添加斜槓的簡單標籤所表示,例如
XML一般用於數據傳送和消息,它存在一些子格式,如RSS和Atom,例如:https://blog.ansheng.me/atom.xml
在Python中解析XML最簡單的方法是使用ElementTree
。
模塊 | 說明 |
---|---|
xml.etree.ElementTree | the ElementTree API, a simple and lightweight XML processor |
導入ElementTree方法,起一個別名爲ET
>>> from xml.etree import ElementTree as ET
建立頂級標籤
>>> level_1 = ET.Element("famliy")
建立二級標籤,tag名name,attrib標籤屬性
>>> level_2 = ET.SubElement(level_1, "name", attrib={"enrolled":"yes"})
建立三級標籤
>>> level_3 = ET.SubElement(level_2, "age", attrib={"checked":"no"})
生成文檔
>>> tree = ET.ElementTree(level_1)
寫入文件中
>>> tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)
導入os模塊,用os模塊中的system方法執行shell命令查看剛纔建立的oooo.xml文件
>>> import os >>> os.system("cat oooo.xml") # 生成出來的文檔是沒有換行的 <famliy><name enrolled="yes"><age checked="no"></age></name></famliy>0
把剛纔生成的文件下載到本地,而後用瀏覽器打開就能夠看到分級層次了。
代碼
from xml.etree import ElementTree as ET from xml.dom import minidom root = ET.Element('level1',{"age":"1"}) son = ET.SubElement(root,"level2",{"age":"2"}) ET.SubElement(son, "level3", {"age":"3"}) # tree = ET.ElementTree(root) # tree.write("abc.xml", encoding="utf-8",xml_declaration=True,short_empty_elements=False) def prettify(root): rough_string = ET.tostring(root, 'utf-8') reparsed = minidom.parseString(rough_string) return reparsed.toprettyxml(indent="\t") new_str = prettify(root) f = open("new_out.xml", "w") f.write(new_str) f.close()
生成的xml文件
<?xml version="1.0" ?> <level1 age="1"> <level2 age="2"> <level3 age="3"/> </level2> </level1>
first.xml
文件內容爲:
<data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year age="19">2025</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year age="19">2028</year> <gdppc>59900</gdppc> <neighbor direction="N" name="Malaysia" /> </country> <country name="Panama"> <rank updated="yes">69</rank> <year age="19">2028</year> <gdppc>13600</gdppc> <neighbor direction="W" name="Costa Rica" /> <neighbor direction="E" name="Colombia" /> </country> </data>
first.xml
文件在/root
目錄下
利用ElementTree.XML將字符串解析成xml對象
>>> from xml.etree import ElementTree as ET # 打開文件,讀取XML內容,將字符串解析成xml特殊對象,root代指xml文件的根節點 >>> root = ET.XML(open('first.xml', 'r').read()) >>> root.tag 'data' >>> for node in root: ... print(node.tag, node.attrib) ... ('country', {'name': 'Liechtenstein'}) ('country', {'name': 'Singapore'}) ('country', {'name': 'Panama'}) >>> print(node.find('rank').text) 69
利用ElementTree.parse將文件直接解析成xml對象
>>> from xml.etree import ElementTree as ET # 直接解析xml文件 >>> tree = ET.parse("first.xml") # 獲取xml文件的根節點 >>> root = tree.getroot() >>> root.tag 'data'
遍歷XML中指定的節點
>>> from xml.etree import ElementTree as ET >>> tree = ET.parse("first.xml") >>> root = tree.getroot() >>> for node in root.iter('year'): # 輸出node的tag和內容 ... print(node.tag, node.text) ... year 2025 year 2028 year 2028
爲節點添加屬性
>>> from xml.etree import ElementTree as ET >>> tree = ET.parse("first.xml") >>> root = tree.getroot() >>> for node in root.iter("year"): # 查看原來的屬性 ... print(node.attrib) ... {} {} {} >>> for node in root.iter("year"): # 添加屬性 ... node.set("OS","Linux") ... >>> for node in root.iter("year"): # 查看添加的屬性 ... print(node.attrib) ... {'OS': 'Linux'} {'OS': 'Linux'} {'OS': 'Linux'} # 把內容寫入文件 >>> tree.write("first.xml")
刪除節點屬性
>>> from xml.etree import ElementTree as ET >>> tree = ET.parse("first.xml") >>> root = tree.getroot() >>> for node in root.iter("year"): # 刪除節點的OS屬性 ... del node.attrib['OS'] ... # 寫入到文件當中 >>> tree.write("first.xml")
查看屬性
>>> from xml.etree import ElementTree as ET >>> tree = ET.parse("first.xml") >>> root = tree.getroot() >>> for node in root.iter("year"): ... print(node.attrib) ... # 節點內容爲空 {} {} {}
修改節點內容
修改year
內的數字自加1
>>> from xml.etree import ElementTree as ET >>> tree = ET.parse("first.xml") >>> root = tree.getroot() >>> for node in root.iter("year"): # 輸出原來year的內容 ... print(node.text) # 原來的值自加+ ... new_year = int(node.text) + 1 ... node.text = str(new_year) ... 2025 2028 2028 # 寫入文件中 >>> tree.write("first.xml") >>> for node in root.iter("year"): # 輸出寫入文件以後year的內容 ... print(node.text) ... 2026 2029 2029
獲取節點的方法
>>> from xml.etree import ElementTree as ET >>> tree = ET.parse("first.xml") >>> root = tree.getroot() >>> print(dir(root)) ['__class__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'extend', 'find', 'findall', 'findtext', 'get', 'getchildren', 'getiterator', 'insert', 'items', 'iter', 'iterfind', 'itertext', 'keys', 'makeelement', 'remove', 'set']
方法有這麼多,那麼咱們經常使用的也就是下面的幾個
方法名 | 說明 |
---|---|
tag | 獲取tag標籤名 |
attrib | 獲取節點的屬性 |
find | 獲取節點的內容 |
iter | 進行迭代 |
set | 設置屬性 |
get | 獲取屬性 |
判斷QQ是否在線
騰訊提供了可以查看QQ號碼是否在線的API,Y
=在線;N
=離線;E
=QQ號碼錯誤;A
=商業用戶驗證失敗;V
=免費用戶超過數量
>>> import requests >>> from xml.etree import ElementTree as ET >>> r = requests.get("http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=6087414") >>> result = r.text >>> from xml.etree import ElementTree as ET >>> node = ET.XML(result) >>> if node.text == "Y": ... print("在線") ... else: ... print("離線") ... 在線
獲取列車起止時間
代碼
r = requests.get("http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=K234&UserID=") result = r.text root = ET.XML(result) for node in root.iter('TrainDetailInfo'): print(node.find('TrainStation').text,node.find('ArriveTime').text,node.find("StartTime").text)
執行結果
C:\Python35\python.exe F:/Python_code/sublime/Week5/Day01/xml_mod.py 上海(車次:K234\K235) None 11:12:00 # 地點 中止 啓動 崑山 11:45:00 11:48:00 蘇州 12:12:00 12:16:00 無錫 12:44:00 12:55:00 常州 13:22:00 13:26:00 鎮江 14:13:00 14:16:00 南京 15:04:00 15:16:00 蚌埠 17:27:00 17:50:00 徐州 19:38:00 19:58:00 商丘 22:12:00 22:17:00 開封 23:49:00 23:53:00 鄭州 00:37:00 01:14:00 新鄉 02:20:00 02:22:00 鶴壁 03:01:00 03:03:00 安陽 03:33:00 03:36:00 邯鄲 04:11:00 04:16:00 邢臺 04:47:00 04:51:00 石家莊 06:05:00 None Process finished with exit code 0
This module implements a common interface to many different secure hash and message digest algorithms. Included are the FIPS secure hash algorithms SHA1, SHA224, SHA256, SHA384, and SHA512 (defined in FIPS 180-2) as well as RSA’s MD5 algorithm (defined in Internet RFC 1321). The terms 「secure hash」 and 「message digest」 are interchangeable. Older algorithms were called message digests. The modern term is secure hash.
官方文檔:https://docs.python.org/3.5/library/hashlib.html
用於加密相關的操做,代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
md5加密
>>> import hashlib m = hashlib.md5() m.update('me'.encode('utf-8')) print(m.hexdigest()) m = hashlib.md5() with open('a','rb') as f: for i in f: m.update(i) md5_num = m.hexdigest() print(md5_num)
sha1
>>> import hashlib >>> hash = hashlib.sha1() >>> hash.update(bytes('ansheng', encoding='utf-8')) >>> hash.hexdigest() 'd1dec3927fbe94ace7f7ebe6c53a844e0265455a'
sha256
import hashlib s = hashlib.sha256() s.update('helloword'.encode('utf-8')) print(s.hexdigest())
sha384
>>> import hashlib >>> hash = hashlib.sha384() >>> hash.update(bytes('ansheng', encoding='utf-8')) >>> hash.hexdigest() '01cab50e3cc7801fec2988573ad62a645daf636a6d2a47d41c7a456113bee6e657a3ff367029f617e38a03d732c8113d'
sha512
>>> import hashlib >>> hash = hashlib.sha512() >>> hash.update(bytes('ansheng', encoding='utf-8')) >>> hash.hexdigest() '79cc48a191152112bd8285979784fc4bba9b0f2d5ac26f96de1ec87a6fbf4935dcb3ba9bc027c3791875b96dd725e01863602f59d4a561bbd2823495cd4553fc'
撞庫實例:
import hashlib passwds=[ 'alex3714', 'alex1313', 'alex94139413', 'alex123456', '123456alex', 'a123lex', ] def make_pass_dic(passwords): dic = {} m = hashlib.md5() for passwd in passwds: m.update(passwd.encode('utf-8')) dic[passwd] = m.hexdigest() return dic def break_code(cryptograph,dic_passwd): for k,v in dic_passwd.items(): if v == cryptograph: print('密碼是--->',k) cryptograph = 'aee949757a2e698417463d47acac93df' break_code(cryptograph,make_pass_dic(passwds))
爲防止別人對咱們的md5值進行撞庫,咱們能夠給md5加個鹽
import hashlib m=hashlib.md5('yihangbailushangqingtian'.encode('utf-8')) m.update('alex3714'.encode('utf-8')) print(m.hexdigest())
另一個加鹽的模塊
import hmac h = hmac.new('egon123456'.encode('utf-8')) h.update('alex3714'.encode('utf-8')) print(h.hexdigest())
根據用戶輸入的登陸名和口令模擬用戶註冊,計算更安全的MD5:
而後,根據修改後的MD5算法實現用戶登陸的驗證.
import hashlib db = {} def calc_md5(password): md5 = hashlib.md5() md5.update(password.encode()) return md5.hexdigest() def register(user,password): db[user] = calc_md5(password + user + 'the-Salt') def login(user,password): p = calc_md5(password + user + 'the-Salt') if user in db: if db[user] == p: print('login successful') else: print('wrong') else: print('can not find',username) while True: x = input('register:1 login:2 quit:0\n') if x == '0': break elif x == '1': user = input('input your name:\n') password = input('input your password:\n') register(user, password) elif x == '2': user = input('input your name:\n') password = input('input your password:\n') login(user, password) else: print('wrong')
import subprocess res = subprocess.Popen('ls',shell=True,stdout=subprocess.PIPE) print(res) print(res.stdout.read().decode('gbk')) #stderr 能夠在出錯是不報錯 res = subprocess.Popen('diasd',shell=True, stderr = subprocess.PIPE, stdout = subprocess.PIPE ) print('---->',res.stdout.read()) print('---->',res.stderr.read().decode('gbk')) res1 = subprocess.Popen(r'ls /Users/boxfish-edu/PycharmProjects/untitled/e',shell=True,stdout=subprocess.PIPE) #print(res1.stdout.read()) res=subprocess.Popen(r'ls test*',shell=True, stdin=res1.stdout, stderr=subprocess.PIPE, stdout=subprocess.PIPE) print('===>',res.stdout.read().decode('gbk'))#管道取一次就空了 print('===>',res.stdout.read().decode('gbk'))#管道取一次就空了
官網介紹:
This module allows you to spawn processes, connect to their input/output/error pipes, and obtain their return codes.
call()
執行命令,並返回狀態碼,狀態碼0
表明命令執行成功,其餘的都表示命令執行不成功
>>> ret = subprocess.call(["ls", "-l"], shell=False) total 4 -rw-r--r-- 1 root root 172 May 25 21:21 file.conf >>> ret 0
另外一種執行方式
# shell=True表示調用原生的shell命令去執行 >>> ret = subprocess.call("ls -l", shell=True) total 4 -rw-r--r-- 1 root root 172 May 25 21:21 file.conf >>> ret 0
check_call()
執行命令,若是執行狀態碼是0,則返回0,不然拋異常
# 執行一個正確的命令就會返回執行結果和狀態碼 >>> subprocess.check_call(["ls", "-l"]) total 4 -rw-r--r-- 1 root root 172 May 25 21:21 file.conf 0 # 若是執行的是一個錯誤的命令,那麼就會返回錯誤信息 >>> subprocess.check_call(["ls", "a"]) ls: cannot access a: No such file or directory Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.6/subprocess.py", line 505, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['ls', 'a']' returned non-zero exit status 2
check_output()
執行命令,若是狀態碼是0,則返回執行結果,不然拋異常
# 執行成功就把執行的結果賦值給變量V >>> V = subprocess.check_output("python -V", shell=True) # 執行錯誤的命令就會輸出異常 >>> subprocess.check_output("pasas", shell=True) 'pasas' 不是內部或外部命令,也不是可運行的程序 或批處理文件。 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python35\lib\subprocess.py", line 629, in check_output **kwargs).stdout File "C:\Python35\lib\subprocess.py", line 711, in run output=stdout, stderr=stderr) subprocess.CalledProcessError: Command 'pasas' returned non-zero exit status 1
以上的三種執行方式在執行命令的時候,shell
默認等於True
,等於True
的時候,括號內的命令是一行的,若是shell
等於False
,那麼[]
內的字符串就是命令的一個元素,執行的時候會把[]
內的字符串拼接起來執行。
subprocess.Popen()
call()
、check_call()
、check_output()
默認內部調用的都是subprocess.Popen()
,而subprocess.Popen()
則用於執行更復雜的系統命令。
參數
參數 | 說明 |
---|---|
stdin | 標準輸入 |
stdout | 標準輸出 |
stderr | 錯誤句柄 |
cwd | 用於設置子進程的當前目錄 |
env | 用於指定子進程的環境變量。若是env = None,子進程的環境變量將從父進程中繼承 |
執行普通命令
>>> subprocess.Popen("Python -V", shell=True) <subprocess.Popen object at 0x0000025C97233C88> # Python 3.5.1是輸出出來的結果 >>> Python 3.5.1
執行命令分爲兩種:
>>> import subprocess # 先進入'/tmp'目錄,而後在建立subprocess文件夾,shell=True無關緊要 >>> subprocess.Popen("mkdir subprocess", shell=True, cwd='/tmp',) <subprocess.Popen object at 0x7f267cc3d390> >>> import os >>> os.system("ls /tmp") subprocess
# 導入subprocess模塊 import subprocess # 執行python命令,進入python解釋器,stdin標準輸入、stdout標準輸出、stderr錯誤輸出,universal_newlines=True自動輸入換行符 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) # 執行標準輸入,write後面是輸入的命令 obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") # 輸入以後關閉 obj.stdin.close() # 讀取標準輸出的內容,賦值給cmd_out對象 cmd_out = obj.stdout.read() # 關閉標準輸出 obj.stdout.close() # 讀取錯誤輸出的內容,賦值給cmd_error對象 cmd_error = obj.stderr.read() # 關閉錯誤輸出 obj.stderr.close() # 輸出內容 print(cmd_out) print(cmd_error)
執行結果
C:\Python35\python.exe F:/Python_code/sublime/Week5/Day02/sub.py 1 2 Process finished with exit code 0
# 導入subprocess模塊 import subprocess # 執行python命令,進入python解釋器,stdin標準輸入、stdout標準輸出、stderr錯誤輸出,universal_newlines=True自動輸入換行符 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) # 執行兩條命令 obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") # communicate把錯誤輸出或者標準輸出的內容賦值給out_error_list對象,若是有錯誤就賦值錯誤輸出,不然就複製標準輸出 out_error_list = obj.communicate() # 輸出out_error_list對象的內容 print(out_error_list)
執行結果
C:\Python35\python.exe F:/Python_code/sublime/Week5/Day02/sub.py ('1\n2\n', '') Process finished with exit code 0
# 導入subprocess模塊 import subprocess # 執行python命令,進入python解釋器,stdin標準輸入、stdout標準輸出、stderr錯誤輸出,universal_newlines=True自動輸入換行符 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) # 直接執行print("hello")命令,而後把錯誤或者正確的結果賦值給out_error_list對象 out_error_list = obj.communicate('print("hello")') # 輸出out_error_list對象的內容 print(out_error_list)
執行結果
C:\Python35\python.exe F:/Python_code/sublime/Week5/Day02/sub.py ('hello\n', '') Process finished with exit code 0
This module defines functions and classes which implement a flexible event logging system for applications and libraries.
The key benefit of having the logging API provided by a standard library module is that all Python modules can participate in logging, so your application log can include your own messages integrated with messages from third-party modules.
官方文檔:https://docs.python.org/3.5/library/logging.html
logging模塊用於便捷記錄日誌且線程安全。
Level | Numeric value |
---|---|
CRITICAL | 50 |
ERROR | 40 |
WARNING | 30 |
INFO | 20 |
DEBUG | 10 |
NOTSET | 0 |
只有大於當前日誌等級的操做纔會被記錄。
代碼
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # 導入logging模塊 import logging # 建立一個log.log日誌文件 logging.basicConfig(filename='log.log', # 格式化的字符串 format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s', # 時間 datefmt='%Y-%m-%d %H:%M:%S %p', # 錯誤級別 level=logging.NOTSET ) logging.critical('critical') logging.error('error') logging.warning('warning') logging.info('info') logging.debug('debug') logging.log(logging.INFO, 'NOTSET')
執行結果
ansheng@ansheng-me:~$ ls log.py ansheng@ansheng-me:~$ python log.py ansheng@ansheng-me:~$ ls log.log log.py ansheng@ansheng-me:~$ cat log.log 2016-05-27 21:46:15 PM - root - CRITICAL - log: critical 2016-05-27 21:46:15 PM - root - ERROR - log: error 2016-05-27 21:46:15 PM - root - WARNING - log: warning 2016-05-27 21:46:15 PM - root - INFO - log: info 2016-05-27 21:46:15 PM - root - DEBUG - log: debug 2016-05-27 21:46:15 PM - root - INFO - log: NOTSET
logging.basicConfig函數各參數
參數 | 說明 |
---|---|
filename | 指定日誌文件名 |
filemode | 和file函數意義相同,指定日誌文件的打開模式,'w'或'a' |
format | 指定輸出的格式和內容,format能夠輸出不少有用信息,以下所示 |
datefmt | 指定時間格式,同time.strftime() |
level | 設置日誌級別,默認爲logging.WARNING |
format參數
參數 | 說明 |
---|---|
%(levelno)s | 打印日誌級別的數值 |
%(levelname)s | 打印日誌級別名稱 |
%(pathname)s | 打印當前執行程序的路徑,其實就是sys.argv[0] |
%(filename)s | 打印當前執行程序名 |
%(funcName)s | 打印日誌的當前函數 |
%(lineno)d | 打印日誌的當前行號 |
%(asctime)s | 打印日誌的時間 |
%(thread)d | 打印線程ID |
%(threadName)s | 打印線程名稱 |
%(process)d | 打印進程ID |
%(message)s | 打印日誌信息 |
對於上述記錄日誌的功能,只能將日誌記錄在單文件中,若是想要設置多個日誌文件,logging.basicConfig將沒法完成,須要自定義文件和日誌操做對象。
#!/usr/bin/env python # _*_ coding:utf-8 _*_ import logging # 建立文件 file_1 = logging.FileHandler("log1.log", "a") # 建立寫入的日誌格式 fmt1 = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s - %(module)s : %(message)s") # 文件用格式 file_1.setFormatter(fmt1) file_2 = logging.FileHandler("log2.log", "a") fmt2 = logging.Formatter() file_2.setFormatter(fmt2) logger1 = logging.Logger("s1", level=logging.ERROR) logger1.addHandler(file_1) logger1.addHandler(file_2) logger1.critical("1111")
# 定義文件 file_2_1 = logging.FileHandler('l2_1.log', 'a') fmt = logging.Formatter() file_2_1.setFormatter(fmt) # 定義日誌 logger2 = logging.Logger('s2', level=logging.INFO) logger2.addHandler(file_2_1)
如上述建立的兩個日誌對象
logger1
寫日誌時,會將相應的內容寫入 l1_1.log 和 l1_2.log 文件中logger2
寫日誌時,會將相應的內容寫入 l2_1.log 文件中This module provides the ConfigParser class which implements a basic configuration language which provides a structure similar to what’s found in Microsoft Windows INI files. You can use this to write Python programs which can be customized by end users easily.
configparser用於處理特定格式的文件,其本質上是利用open來操做文件。
# 第一種註釋方式 ; 第二種註釋方式 [node1] # 節點 k1 = v1 # key = value k2 : v2 # key : value
import configparser #爲文件添加節點 config=configparser.ConfigParser() config.read('a.ini',encoding='utf-8') config.add_section('node1') config.add_section('node2') config.write(open('a.ini','w')) #檢查節點是否存在 print(config.has_section('node1')) #存在返回True #刪除節點 config.remove_section('node2') config.write(open('a.ini','w')) #設置節點內的鍵值對 config.set('node1','name','ansheng') config.set('node1', 'Blog_URL', "https://blog.ansheng.me") config.set('node1', 'Hostname', "localhost.localhost") config.set('node1', 'IP', "127.0.0.1") config.write(open('a.ini', 'w')) #檢查節點內的key是否存在 #若是節點的Key存在就返回"True",不然返回"False" print(config.has_option('node1', 'Name')) #刪除節點內的key #若是刪除的節點存在就返回"True",不然就返回"False" print(config.remove_option('node1', 'IP')) #獲取指定節點下指定key的值 print(config.get('node1','name')) #返回的字符串咱們能夠設置成一下三種數據類型,分別是"int","float","bool" v = config.getint('node1', 'name') v = config.getfloat('node1', 'k1') v = config.getboolean('node1', 'k1') #獲取指定節點下全部的key #返回節點下面全部的Key列表 print(config.options('node1')) #獲取指定節點下全部的鍵值對 #返回一個列表,列表中每一個元組就是一個鍵值對 print(config.items('node1')) #獲取全部節點 #獲取當前文件中有多少個節點 print(config.sections())
執行文件都是test.py 1. import glance.api.policy.get #報錯,點的左邊必須是包 import glance.api.policy glance.api.policy.get() 2. from glance.api import policy,versions from glance.cmd import manage from glance.db import models policy.get() manage.main() models.register_models('mysql') --- #注意與本文件內函數名之間的衝突 from glance.api.policy import get from glance.api.versions import create_resource from glance.cmd.manage import main from glance.db.models import register_models get() create_resource('mysql') main() register_models('mysql') 3. #前提在api下的__init__.py內加入__all__=['policy','versions'] from glance.api import * policy.get() print(policy) print(versions) 4. #前提在glance下的__init__py配置 from .api import * #policy,versions from .cmd import * #mange from .db import * #models #test.py import glance glance.policy.get() glance.versions.create_resource('mysql') 備註: import glance print(glance) 直接倒入glace打印的是glace下的__init__.py 實例目錄結構: 包能夠是結構更清晰,便於開發者修改 ''' ---glance | --api | ---__init__py ---policy.py ---versions.py --cmd | ---__init__.py ---manage.py --db | ---__init__.py ---models.py __init__.py '''