1. 程式人生 > >python學習的所有練習記錄

python學習的所有練習記錄

# set  集合  特點,無序,不重複,如果重複物件傳入只儲存一份,
# 應用場景,比如記錄爬蟲訪問記錄,有重複的就直接不用新增,如果用列表就還需要判斷是不是存在,比如前面的購物車連結新增購物清單的時候
# 具體方法看原始碼即可
# se={"112","323"} # create
# print(type(se))

# ret =se.pop() # 這個的移除是隨機的,所以不太實用,但是會將移除的結果返回到變數中
# se.discard("112") # 如果移除的元素存在,則移除,不存在則不處理,也不會報錯

# list=["112,223"]
# print(list[0].__str__())
# se.add(list[0].__str__())
# se.add(list[1].__str__())
# print(se)

'''
# 練習題
old_dict={
"1":"223",
"2":"44",
"3":"562"
}

new_dict={
"1":"52",
"2":"5",
"5":"92"
}

# 找出在old存在,new不存在的key,進行刪除 思路,利用set的diffrent方法找不同key然後利用key去刪除
old_keys=old_dict.keys()
new_keys=new_dict.keys()
# print(old_keys,"\t",new_keys)
old_set=set(old_keys)
new_set=set(new_keys)
cy=old_set.difference(new_set)
for i in cy:
print("要刪除的key是",i)
del(old_dict[i])
print(old_dict)

# 找出都存在的進行更新,intersection獲取交叉的key進行更新
jc=old_set.intersection(new_set)
for i in jc:
print("現在要更新的key是:",i)
old_dict[i]=new_dict[i]
print(old_dict)
# 找出old中不存在,但是new中存在的進行新增
xz=new_set.difference(old_dict)
for i in xz:
old_dict[i]=new_dict.get(i)
print(old_dict)
'''

'''
list1=[1,2,4]
list2=[1,3,5]

# s1={"1",list1}
# s2={"2",list2}
# s1.difference(s2)

# 上面宣告就會直接報錯但是可以這樣
set1=set(list1)
print(set1)

# s1={"1","2"}
# s1.add(list1)
'''

# 普通引數,嚴格按照順序和型別將實際引數賦值給形式引數
# 預設引數,必須放在引數列表最後
# 指定引數,將實際引數賦值給指定的形式引數

'''
# 函式的動態引數這裡,總覺得不是很明確,傳入之後如何引用
# 測試說明,傳入的引數都當做一個元組來進行處理,
def dtcs(*wew): # 這裡的引數名稱不是固定的為args,其他形式也沒有報錯
print(type(wew),wew)




list=[1111,"2323",2323]

# 當然這裡有個地方要進行說明當我們這種的形式傳入,會將傳入的列表當做元組的一個元素傳入<class 'tuple'> ([1111, '2323', 2323],)
dtcs(list)
# 當以星號附帶傳入,就是將列表中的元素取出放到元組中 <class 'tuple'> (1111, '2323', 2323),
# 如果傳入一個字串,會將字串每個字元取出來傳入 ,傳入str="lipeng" 結果<class 'tuple'> ('l','i','p','e','n','g')
dtcs(*list)


# 當然還有兩個星號的動態引數,型別是字典,主要是用來傳入多個字典形式的,必須指定鍵值對比如n1=23
def dtcs2(**kwargs):
print(type(kwargs),kwargs)

# dtcs2(age=18,name="xiaoding")

# 當然,和上面一樣,如果我們希望以鍵值本身的形式傳入<class 'dict'> {'age': 18, 'name': 'xiaoding'},
# 需要寫入星號的形式,否則的話,需要寫成上面那種形式
dict1={"age":18,"name":"xiaoding"}
# dtcs2(dict1) # 當然這樣是不行的
dtcs2(**dict1)


# 另外就是可以接收任意引數的形式,在這種形式下,會自動判斷鍵值對的引數到兩星,單獨的值到一星裡,另外就是兩個星的必須在後面
def wncs(*args,**kwargs):
print(args)
print(kwargs)

'''

'''
# 格式化字串,一種是我們常用的%s %d,這種比較熟悉了,我們記錄一下另一中{}佔位,形式str.format()
s="我是一個{0},我今年{1}".format("小丁",12)
print(s)
# 當然也可以有另一種形式
my=["xiaoding",12]
s="我是一個{0},我今年{1}".format(*my)
# 也可以是下面的形式
s="我是一個{name},我今年{age}".format(name="xiaobai",age=18) # 通過引數名稱進行的格式化,當然換成字典也和上面的列表一樣d
print(s)


# 函式的引數傳遞的是引用還是一份新的資料物件,結果說明傳遞的只是一份引用,實際對元資料進行了修改
def lpc(a1):
a1.append(5555)

list=[1,2,3,4]
lpc(list)
print(list)

# 另外就是要注意函式變數的作用域,作用域越小,級別越高比如
name="lipengchao"
def xuesheng(name):
name="xiaoding" #區域性變數,自己擁有先使用自己的,沒有的話再去全域性變數尋找
# 如果想要修改全域性的而不是自己的,重新對全域性變數賦值,需要使用關鍵字global,
# 不過個人還是喜歡使用傳入和return返回,不喜歡這種形式,雖然是複製了一份新的,但是看個人習慣吧
# global name
# name="xiaobai"
print("xuesheng",name)

def xuesheng1():
# 如果想要修改全域性的而不是自己的,重新對全域性變數賦值,需要使用關鍵字global,
# 不過個人還是喜歡使用傳入和return返回,不喜歡這種形式,雖然是複製了一份新的,但是看個人習慣吧
global name
name="xiaobai" # 只能先宣告在進行修改
print("xuesheng1",name)

xuesheng(name)
xuesheng1()
print("外部",name) # 這裡會返回全劇的,函式內的修改並不影響全域性的,



# 這裡有個問題就是函式返回值的問題
li=[11,33,545]
def fun(li):
li.append(5443)

li=fun(li) # 但是這一步需要注意,這裡將返回值none賦值給li,這樣就報錯了 'NoneType' object has no attribute 'append'
fun(li) # 經過處理後 [11, 33, 545, 5443]
print(li)
'''

### 一般情況下,全域性變數都設定為大寫,區域性變數為小寫,這樣可讀性高

'''
# 三元運算 或者成為 三目運算 這樣一句話可以替換簡單的if else表示式
name="lipengchao" if 1==2 else "xiaoding"
# 雖然和Java的格式不太一樣,但是道理一樣,條件成立一個值,不成立取else的值,當然如果你不嫌棄麻煩,也可以用if else去寫
print(name)

# lambda 一句話用來替換比較簡單的(沒有方法體可用)函式,比如
def f1(a1):
return a1+100

print(f1(10))
# 替換成lambda就是
result=lambda a1:a1+100 # 只需要寫引數和返回值,其他的都唄替換成關鍵字lambda,如果有多個引數和返回值用逗號隔開,當然也可以使用預設引數
result1=lambda a1,a2=12:a1+a2
print(result(10))

'''
'''
# 內建函式,這些功能就不用自己再去實現了
abs(-1) # 獲取絕對值
# 0或者空的物件轉為布林值都是False,
# all() # 接收一個可以迭代的物件,如果迭代後所有的物件都是真為真,否則為假
list=[1,2,""]
print(all(list))

any(list) # any也是接收一個可以迭代的物件,只要有一個為真則為真,可以用來判斷物件是不是一個空的物件

ejz=bin(23) # 接收十進位制轉為二進位制 0b10111 ob表示二進位制的代稱 10111
bjz=oct(23) # 接收十進位制轉為八進位制 0o27 0o表示八進位制
sljz=hex(23) # 接收十進位制轉為十六進位制 0x17 0x 表示十六進位制

print(ejz,bjz,sljz)



# bytes用來將字串轉為位元組,位元組再變成二進位制儲存在硬碟上,(utf-8一個漢字佔用三個位元組,gbk一個漢字佔用兩個位元組 每個位元組是8位表示)
print(bytes("位元組",encoding="utf-8")) # b'\xe5\xad\x97\xe8\x8a\x82' 轉為16進位制儲存的位元組數更少,但是底層需要轉為二進位制
print(bytes("位元組",encoding="gbk")) # b'\xd7\xd6\xbd\xda'

print(str(bytes("位元組",encoding="utf-8"),encoding="utf-8")) # 位元組 再轉回來



# callable() # 判斷是否可以被呼叫,引數傳入物件

# 用於轉換ascII碼和字元
zf=chr(65) # 將十進位制碼轉為對應的字元A
print(zf)
bm=ord("A") # 將字元轉為編碼
print(bm)
'''

'''
# 檔案操作,開啟檔案,操作檔案,關閉檔案
# f=open(file="text",mode="",encoding="")# 我們自己操作預設都使用utf-8如果讀入是亂碼,可以試試gbk
# f.read() # 也可以傳入行號
# f.close()
# 模式:r 只讀,w 清空檔案後寫入,x 當檔案存在報錯,不存在,建立檔案進行寫入, a 追加
# f=open(file="text",mode="r",encoding="utf-8")# 我們自己操作預設都使用utf-8如果讀入是亂碼,可以試試gbk
# f.read() # 也可以傳入行號
# f.close()
# 如果模式增加b就是以字元方式操作,比如rb那麼Python就不在幫助我們進行轉換,那麼就需要自己處理位元組和字串轉換處理(bytes,str)
# f=open(file="text",mode="wb")# 二進位制不需要指定編碼
# f.write(bytes("李鵬超",encoding="utf-8")) # 需要指定編碼
# f.close()
#
# f=open(file="text",mode="rb")# 二進位制不需要指定編碼
# data=f.read()
# print(str(data,encoding="utf-8"))
# f.close()


# 如果增加+那就是可讀可寫
# f=open(file="text",mode="r+",encoding="utf-8")
# # data=f.read(1) # 讀出之後指標會在最後的位置,沒有引數讀取全部內容,如果有引數,b讀取位元組,如果沒有b按字元讀取
# data=f.readline() # 讀取當前指標所在的一行資料,對於讀取大檔案只判斷每一行效率上很有好處
# print(data)
#
# # 迴圈獲取檔案物件每一行的內容
# for line in f:
# print(line)
#
# # 寫入的時候在指標所在的位置進行寫入,如果後面有內容會進行覆蓋,覆蓋的時候如果是b位元組的形式,會每次覆蓋一個字元,
# # 如果是字元形式,那麼會每次覆蓋一個字元的位置,當然這裡有一個指定指標位置的方法,
# # 一般都是使用r+ a+無論指定那個位置都會在最後追加,w+會將檔案先清空在讀寫
# f.seek(0) # 傳入指標的位置,
# f.truncate() # 清空指標所在位置之後的內容
# f.seekable() # 是否可以引動指標
# print("當前指標的位置在",f.tell())# 獲取當前指標的位置
# f.flush() # 將現在記憶體的內容儲存到硬碟去
# f.readable() # 判斷是否可讀,返回布林值
# f.writelines("插入內容")
#
#
#
# print(f.fileno()) # 獲取一個檔案的數字變現形式,修改後會有變化,可以監控檔案是否被修改過
# f.close()

# 通過with操作檔案,模組會操作完成自動關閉,2.7之後可以支援讀取多個檔案,對於需要多個檔案內容拼接一個內容,或者轉換檔案內容比較有效
# 演示的是將第一個檔案的內容插入到第二個檔案,當然也可以根據需要進行截斷
with open(file="text",mode="r",encoding="utf-8") as fr,open(file="text1",mode="w",encoding="utf-8") as fw:
for line in fr:
print(line) # 當然這個地方也可以對內容進行處理,比如replace或者split
fw.write(line)


with open("text","r+",encoding="utf-8") as f:
for line in f:
if line.strip().startswith("插入內容") and "4" in line.strip():
print(line.strip())
break

# print(f.tell())
f.write("\n新增內容\t20181017") # 新增換行
'''

'''
import random
MIN=65
MAX=90 # 這個範圍是所有的大寫字母

# 隨機產生驗證碼,我們來隨機產生四個字母
def scyzm(max,min):
sjs=random.randrange(min, max)
zf=chr(sjs)
print(sjs,zf)
return zf

yzmlist=[];
for i in range(6):
if i==random.randrange(1,4):
sz=random.randrange(0, 10);
yzmlist.append(str(sz)) # 數字就直接拼接
else:
zf=scyzm(MAX, MIN)
yzmlist.append(zf)
result="".join(yzmlist)
print(result)
# 用於轉換ascII碼和字元
# zf=chr(126) # 將十進位制碼轉為對應的字元A
# print(zf)
# bm=ord("A") # 將字元轉為編碼
# print(bm)
#
s="print(123)"
# 編譯,獲取一個編譯物件,當然也可以傳入開啟的檔案物件,三種模式 single(編譯成單行),eval() 編譯成一個表示式 ,exec 編譯成和Python程式碼執行一樣的東西
r=compile(s,"<string>","exec") # 主要作用就是將字串編譯成Python程式碼

# 執行Python程式碼或者字串,其實exec如果是接收的編譯過的就直接執行,如果是接收到字串,就先編譯一下
exec(r)

# eval() 將表示式型別的字串編譯成一個表示式並獲取表示式的計算結果,在處理excel的時候很有作用,當然了exec 可以執行所有的Python程式碼,但是沒有返回值,而eval有
s="8*8"
print(eval(s)) # 可以獲取返回的結果
# print(exec(r)) # 也可以執行,但是沒有返回值,返回值就是兩個的重點區別
#
#
# print(dir(dict)) # 傳入一個物件,閱覽物件提供的方法和功能
help(list) # 檢視物件的幫助資訊,其實就是讀取了原始碼的註釋,自己也可以去檢視原始碼來獲取幫助

# 獲取商和餘數,比較實用的列子就是分頁divmod
n1,n2=divmod(97,10)
print(n1,n2) # 9 7

s="lipengchao"
print(isinstance(s,str)) # 用來判斷物件是不是型別的例項


# filter 引數:1函式 2 可迭代的物件 如果引數1為None,那麼就全部為真,返回迭代物件的全部值,
# 功能:對引數2中符合引數1要求的條件資料進行過濾
# 將第二個引數的每一個物件帶入到第一個引數中去執行,如果返回真就將當前的迴圈到的底下那個進行儲存,否則就進行拋棄,大致相當於
# result=[];
# for item in 引數2:
# r=第一個引數(item);
# if r:
# result.append(item)
def f1(a):
if a>32:
return True
f2=lambda a:a>32
print(f2(10))

lb1=[11,233,443,2,42,98] # 儘量不要使用關鍵字去命名,這樣會造成很多不可知的錯誤
result=filter(lambda a:a>123,lb1)
print(list(result))

# map 對引數二的迭代物件中每個元素做引數一函式中的操作,這樣做的作用一般就是程式碼可以簡潔一些,不用去寫迴圈的部分
result=map(lambda a:a+200,lb1)
print(list(result))

# map 是將函式的返回值新增到結果中,filter是將能使函式返回True的迴圈物件新增到返回結果中

# globals() 所有的全域性變數 locals() 儲存所有的區域性變數
# def f3():
# a=0;
# b=0;
# # print(globals());
# print(locals()) # {'b': 0, 'a': 0}
#
# f3()

s="李鵬超"
# print(hash(s)) # 作用就是將一個物件轉存為一個雜湊值,方便儲存和查詢
# print(id(s)) # 獲取記憶體地址
# issubclass() # 判斷一個類是不是另一個類的子類
# print(len(s)) # Python3預設按照字元計算,Python2中預設按照位元組計算,而且也只能按照位元組計算,3中就可以轉換bytes後按位元組統計

for i in s:
print(i);

# max 最大 min 最小 sum 求和

# 次方 兩種形式
2**10
pow(2,10)

# 反轉
lb1.reverse();

# round 四捨五入
round(2.4)
# zip 將傳入的可迭代物件,相同下標的組成一個元組,所有共有下標拼接的元組組成一個列表
# lb1=["xiaoding","18","aihao"];
# lb2=["xiaoxin","18"];
# lb3=["xiaobai","18"];
#
# re=zip(lb1,lb2,lb3)
# print(list(re)) # [('xiaoding', 'xiaoxin', 'xiaobai'), ('18', '18', '18')]

'''

'''
# json 進行資料的互動和儲存,在Python中可以將字串轉換為Python的基本資料型別,如果存在需要引號的地方,必須字串裡是雙引號
import json
s1='["名字",233]'
l1=json.loads(s1)
print(l1)
'''

'''
def f1():
print(123)

def f2(fun):
fun();

f2(f1) # 多增加括號,和不增加括號效果一樣,只是執行了f1

######################################## 裝飾器 主要是用來控制權限的操作 ########################################

# 功能 1 就是在不改變函式內部的情況下,增加外部程式碼來增加一個額外的功能,在函式的前後都可以新增一些功能
# 2 將裝飾函式的返回值重新賦值給被裝飾函式
# 形式 @ + 函式名
# 位置: 放在要執行的函式上 會被自動執行,並且會自動將下面的函式當做引數傳入

def f4(aaa):
print("裝飾器函式的內部語句") # 裝飾函式f4內部的語句
# 函式名代指整個函式,加上括號,則執行函式
aaa(); # 如果需要f3原函式,則可以進行執行,所以就是被呼叫的原函式可以執行也可以不執行,另外前後都可以新增語句
return "被呼叫函式的更新後內容"; # 新的f3函式內容


@f4
def f3():
print("被裝飾的函式也就是被呼叫函式內部的原始語句")

# 如果有返回值的情況下,就不能像上面那樣操作

def f5(aaa):
def f7():
print("函式前新增的功能")
# 函式名代指整個函式,加上括號,則執行函式
f6res=aaa(); # 如果需要f3原函式,則可以進行執行,所以就是被呼叫的原函式可以執行也可以不執行,另外前後都可以新增語句
print("函式後新增的功能")
return f6res
return f7; # 新的f6函式內容


@f5
def f6():
print("被裝飾的函式也就是被呼叫函式內部的原始語句")
return "原函式的返回值66666666666"

print(type(f6),f6()) # 賦值之後,連被裝飾函式f3的屬性都變成了裝飾函式的返回值


# 原函式在有引數的情況下,
# 問題:開始呼叫的時候f8是有引數的,但是第二次f8變成了f10之後,是不要引數的
# 其實有這個問題,並不存在,因為在開始呼叫的時候,其實呼叫的是f10,f10需要一個一樣的引數就可以了

def f9(aaa):
def f10(name): # 當然如果想要徹底解決引數的問題,可以使用*args,**kwargs
print("函式前新增的功能")
res=aaa(name); # 當然如果想要徹底解決引數的問題,可以使用*args,**kwargs
print("函式後新增的功能")
return res
return f10;


@f9
def f8(name):
print("被裝飾的函式也就是被呼叫函式內部的原始語句",name)
return "原函式的返回值88888888888"

print(type(f8),f8("xiaoding"))

# 總結上面就是在原始函式不變的基礎上,對原函式的功能進行了擴充


import sys
list1 = [{'name': 'xiaoming', 'password': 'xiaoming', 'ye': 500, 'jb': '1', 'zt': '1'}, {'name': 'xiaoding', 'password': '12', 'ye': 300, 'jb': '2', 'zt': '1'}, {'name': 'xiaobai', 'password': '1', 'ye': 100, 'jb': '3', 'zt': '1'}]
namelist=[];
for u in list1:
namelist.append(u.get("name"))
sys.exit(2)

print("xiaoding" in namelist)
'''

'''
# 格式化字串,個人覺得使用format的方式可讀性,易用性都比較好
# 百分號格式的
# 格式化字串當格式化的時候,字串中出現了使用%作為佔位符的話,如果想要輸出一個%字串,就必須通過%進行轉義
# print("我是一個%s,現在輸出百分號%%"%"小丁")
# # 如果沒有出現,那麼就可以只寫一個
# print("我是一個小丁,現在輸出百分號%")
# # 保留指定小數位數,四捨五入
# print("我是一個小丁,今年的年齡是%.2f"% 23.333333241)

# format格式 語法格式:[fill空白處填充字元[align對齊方式需要width配合[width[,逗號是對位數較多的進行逗號分割[.2小數保留精度[type資料型別]
# s="《{}》年齡《{}》愛好《{}》".format("xiaoding",18,"papapa") # 裡面也可以是空的,按照順序進行賦值

# yuanzu=("xiaoding",18,"papapa")
# s="《{}》年齡《{}》愛好《{}》".format(*yuanzu) # 這裡和傳參的時候意思一樣,可以將物件內的值對應傳入,**也是一樣的意思 《xiaoding》年齡《18》愛好《papapa》
# s="《{0[0]}》年齡《{0[1]}》愛好《{0[2]}》".format(yuanzu) # 還支援對傳入的引數進行按下標取值

# s="《{0}》,《{0}》《{1}》".format("插入內容1","插入的內容2") # 首先要說的就是一個引入可以重複去賦值.沒有名字,按順序對應

# s="《{name:s}》《{age:d}》".format(name="xiaoding",age=12) # 當然也可以不指定型別,系統自動判斷型別

# s="{:.2%}".format(0.23444) # 百分號與上面的不同,這裡是自動將小數或者整數轉為百分比的形式,保留小數位數

# s="《{:s}》年齡《{:d}》考試成績是《{:.2f}》".format("xiaoding",23,23.333); # 只指定資料型別,第一個必須是字元,第二個必須是整數,等等

# 也可以轉進位制,轉進位制必須是整數,小數是無法轉的,後面的值可以比需要的多,但是不會被使用,當然,下面的這種下標方式,用名字也是可以的
# s="《{0:s}》年齡《{1:d}》考試成績是《{2:.2f}》,成績的二進位制是【{2:b}】,八進位制是【{2:o}】,十六進位制是【{2:x}】,佔平均成績的《{3:.2%}》".format("xiaoding",23,84,1.23323);
#
# print(s)
'''

'''
# 生成器,主要作用就是在你需要用這個數值的時候才將這個數值載入到記憶體,不會一次性將所有的數值全部載入到記憶體中,有yield關鍵字就是生成器

list1=[11,22,33,4,44];

# res=filter(lambda x:x>22,list1) filter 過濾
# print(res.__str__())

def scq(list1):
for sj in list1:
yield sj;

res=scq(list1) # 沒有被使用的時候,獲取到一個具有生成數值的物件,這個就是生成器


# 迴圈將物件內的資料取出來,進入函式將yield關鍵字後面的數值取出來,可以將資料取出來的就是迭代器,兩種形式
# for i in res:
# print(i)

# 也可以使用這種形式,相當於每次都自己去取出來,不如for迴圈好用,迭代器的內部實現
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
# print(res.__next__()) # 沒有資料會報錯
'''

'''
# 遞迴函式
def func(mingzi):
mingzi=mingzi*2;
if len(mingzi)>20:
return mingzi;
return func(mingzi);

print(func("xiaoding"))

# 思考題:1*2*3*4*5*6*7
list1=[];
def func(arg):
print(arg)
list1.append(arg)
arg+=1
if arg>=8:
return list1
return func(arg)

print(func(1))
'''

'''
# 匯入模組,當然如果要新增目錄可以將路徑新增到列表中,需要注意的就是,如果前面的路徑已經存在和系統重複的名稱,會導致匯入的包不是你想要的,所以命名要多注意包名不要和系統包名衝突
import sys
for lj in sys.path: # 匯入模組的所有路徑以及順序,我們可以看到,是自己的專案路徑優先,其次是Python的安裝包,然後是第三方安裝包
print(lj)

# 匯入的方式 import 模組名 或者 from 模組名 import 函式名 當然都支援as 別名

# 安裝第三方包
# 1 pip install 包名 線上
# 2 原始碼安裝:下載原始碼解壓--進入這個目錄 Python setup.py install
# 3 使用pycharm方式去處理
# 當然如果有依賴還需要處理依賴

'''

# 序列化,將程式資料型別轉為字串,反序列化,就是將字串轉為程式資料型別
import json
import pickle

# dic1={"1":"1","2":"2","4":"4","5":"5","3":"3"}
# res=json.dumps(dic1); # 將程式資料型別轉為字串
# print(type(res),res)
# res=json.loads(res) # 反序列化,就是將字串轉為程式資料型別
# print(type(res),res)
'''
import requests
response=requests.get("http://wthrcdn.etouch.cn/weather_mini?city=西安")
response.encoding="utf-8"
# print(type(response.text),response.text)
tq=json.loads(response.text)
tq=tq.get("data")

print("城市:",tq.get("city"))
print("空氣指數:",tq.get("aqi"))
print("感冒建議:",tq.get("ganmao"))
print("當前溫度:",tq.get("wendu"))
# s1="<![CDATA[<3級]]>"
# print(s1[s1.index("[",6,len(s1))+1:s1.index("]",6,len(s1))]) # 切片包前不包後

wtyb=tq.get("forecast");
print("\n\n下面是五天的天氣預報:")
for mt in wtyb:
fl=mt.get("fengli")
fl=fl[fl.index("[", 6, len(fl)):fl.index("]", 6, len(fl))+ 1]
s="日期:{date}\t\t\t{type}\t\t\t最高溫度:{high}\t\t\t最低溫度:《{low}》\t\t\t風力:{fengli}\t\t\t風向:{fengxiang}"\
.format(date=mt.get("date"),type=mt.get("type"),high=mt.get("high"),low=mt.get("low"),fengli=fl,fengxiang=mt.get("fengxiang"))
print(s)

import datetime
xiaoshi=datetime.datetime.now().strftime("%H")
print(xiaoshi,type(xiaoshi))

'''

'''
# 像其他程式傳遞json的時候,由於其他程式基本都是雙引號比較字串,所以最好是
s1='["122","333","222"]'
print(json.loads(s1))
# 雖然說在Python中雙引號在外,或者單引號在外都是正確的,另外相比較dumps和loads,dump=dumps+寫入檔案 load=讀取檔案+loads
with open("jsontext20181024","w") as jf:
dumpres=json.dump(s1,jf)

with open("jsontext20181024","r") as jf:
loadres=json.load(jf)
print(loadres)

# pickle 只能Python能操作,不能跨語言,當然也是dumps和loads ,dump 和load 用法和效果和上面都一樣
# 表面上看json更加完美一些,事實上,json只支援Python的基本資料型別適合跨語言去操作,
# 而pickle支援python所有型別,可以對Python類等複雜的物件進行序列化,另外就是Python不同版本也可能會存在不能序列化
'''

# 時間模組常用功能,如果判斷時間物件的大小,直接用符號對比就可以了
'''
import time

# tm_wday 0到6 (0是週一) tm_yday 1 到 366(儒略曆)
# 獲取時間戳 從Unix正式上線1970-01-01開始計算的秒數
print("1111",time.time())
# <class 'str'> Thu Oct 25 09:12:18 2018 輸出當前時間時間的字串格式,傳入一個時間戳來獲取指定時間戳的對應時間
print("2222",type(time.ctime()),time.ctime())
# 以物件的形式輸出當前時間的所有屬性,傳入時間戳的話就是指定時間戳的時間物件,但是這個預設時區有個問題,中國的東八區要差八個小時
print("獲取標準時區的時間物件",time.gmtime())
# 獲取本地時間物件
print("獲取本地時間物件",time.localtime(time.time()))
# 需要時間物件引數,將時間物件轉為時間戳
print("33333",time.mktime(time.localtime(time.time())))
# 讓程式停止指定的秒數
print("現在我要休息三秒")
time.sleep(3)
print("休息完成")
# 將時間物件轉為一個指定的字串格式
print("將時間物件轉為一個指定的字串格式",time.strftime("%Y-%m-%d %H-%M-%S",time.localtime(time.time())))

# 將字串按照指定的格式轉為時間物件
print("將字串按照指定的格式轉為時間物件",time.strptime("2018-10-25 09-37-46","%Y-%m-%d %H-%M-%S"))


import datetime
# 當前時間 注意兩種型別
dqsj1=datetime.datetime.today()
print("當前時間",type(dqsj1),dqsj1) # 秒後面的單位微秒可以計算程式執行時間
print("當前日期",type(datetime.date.today()),datetime.date.today())
dqsj2=datetime.datetime.now()
print("當前日期",type(dqsj2),dqsj2)
print("時間差異是:",dqsj1-dqsj2)

print(dqsj1.replace(year=2020,month=8)) # 為了跳轉到指定的日期,不用複雜的運算,時間物件直接跳轉到指定日期,沒有指定的屬性部分取當前時間的
# 將時間戳轉為時間
print(datetime.date.fromtimestamp(time.time()))
print(datetime.datetime.fromtimestamp(time.time()))
# 增加指定的時間,可以點進去看下,timedelta有很多引數可以使用
print(datetime.datetime.now()+datetime.timedelta(weeks=1))
# print(datetime.datetime.now()+10) 直接加就報錯了

'''

'''
# 日誌模組
# 級別:debug 詳細執行日誌 info 自己想要記錄下,沒啥特別的 warning 警告和提醒 error 一般錯誤 critical 嚴重錯誤
# 基本設定,日誌的記錄檔案,記錄日誌的最低級別,時間格式,測試說明,第一個配置配置過了,後面的配置不起作用
import logging
# 基本設定,日誌的記錄檔案,記錄日誌的最低級別,時間格式,測試說明,第一個配置配置過了,後面的配置不起作用
logging.basicConfig(filename="/media/lipengchao/study/pycharmproject/lx20171110/jinggao.log",level=logging.WARNING,format="%(asctime)s%(message)s",datefmt="%Y-%m-%d %H:%M:%S")
# logging.basicConfig(filename="/media/lipengchao/study/pycharmproject/lx20171110/test.log",datefmt="%Y-%m-%d %H:%M:%S ") # 不指定級別預設就是警告以上的

# 寫入日誌的方法
logging.debug("詳細執行日誌"); # 可以看到預設debug和info是不打印出來的
logging.debug("系統啟動了")
logging.info("自己想要記錄下,沒啥特別的")
logging.warning("警告,不要嘚瑟")
logging.error("一般錯誤"); # 錯誤和嚴重會被打印出來
logging.critical("嚴重錯誤"); # 嚴重,重要



# 如果沒有配置檔案,那麼就列印在螢幕上,否則列印在檔案裡,如果檔案和螢幕都需要輸出
# 定義一個寫日誌的物件
logger=logging.getLogger("lipengchao") # 寫日誌的物件
logger.setLevel(logging.DEBUG) # 設定一個全域性的日誌級別,這樣的話,debug這些也就記錄在裡面了
# logger.debug("aaaa李鵬超賬戶記錄的日誌") # 記錄的和上面一樣,沒有使用者

# 日誌輸出在哪裡的物件 handler
sh=logging.StreamHandler() # 輸出到螢幕的物件
sh.setLevel(logging.WARNING) # 設定螢幕輸出的級別,如果沒有就使用全域性的

fh=logging.FileHandler("/media/lipengchao/study/pycharmproject/lx20171110/wjpmtssc.log");
fh.setLevel(logging.WARNING) # 設定檔案輸出的級別,如果沒有就使用全域性的,並且這個級別不能比全域性的級別低,否則按全域性的級別執行

# 設定每個handler輸出的格式# formatter(filename)s,注意文字是s 數字要用d,最有用的就是那個模組的哪一行 module lineno
gszd={"asctime":"時間","name":"使用者名稱","levelname":"日誌級別名稱","filename":"寫日誌的檔名稱","module":"寫日誌的模組名稱","funcName":"寫入日誌的函式名稱","lineno":"寫入日誌的程式碼行號","message":"日誌資訊","process":"程序號","pathname":"路徑名稱","processname":"程序名稱","thread":"執行緒id","threadname":"執行緒名稱","":"","":"",};
pmformatter=logging.Formatter\
("螢幕日誌:(asctime)s-(name)s-(filename)s-(levelname)s-(lineno)d-(funcName)s-(module)s-(message)s");
wjformatter=logging.Formatter("檔案日誌:(asctime)s-(name)s-(levelname)s-(message)s");

# handle繫結formatter
sh.setFormatter(pmformatter)
fh.setFormatter(wjformatter)

# logger繫結handle
logger.addHandler(sh)
logger.addHandler(fh)

# 使用logger物件進行日誌的記錄
print("金額:¥%d 元" % 1.6000)
print('%f' % 1.12345678)

'''
# import time
# import datetime
# def pd():
# pdsj=datetime.strptime("2017-10-18","%Y-%m-%d")
# kssj=datetime.strptime("1991-01-01","%Y-%m-%d")
#
# # kssj = datetime.timedelta(1)
#
#
#
# pd()
'''
程式檔案說明
bin 執行檔案,程式入口
conf 程式配置檔案,一些需要使用者輸入的配置放到這裡來獲取
modules/core 核心邏輯
log 日誌
db 儲存資料

'''
# 作業題
'''
# 第一
li=["11","22","33","44"]
print("-".join(li))

# 第二
li = ["alec", " aric", "Alex", "Tony", "rain"]
tu = ("alec", " aric", "Alex", "Tony", "rain")
dic = {'k1': "alex", 'k2': ' aric', "k3": "Alex", "k4": "Tony"}

dict1={"li":li,"tu":tu,"dic":dic};
'''

'''
# 20181109 通過遞迴完成階乘 假設從1乘到7

def func(num):
if num==1:
return 1
# print(num) 理解起來不太好理解,主要是在函式返回結果的時候再次調動函式打到函式重複執行的目的
return num*func(num-1)

print(func(5))
'''


# 反射: 利用字串去指定模組中操作(查詢獲取getattr,檢查hasattr,刪除delattr,增加setattr)指定成員的功能的機制
# 但是這些操作都只是針對記憶體進行操作,重新載入之後,依舊恢復檔案內的內容


'''
import com.lpc.Basic.kztgw3 as gncs

userChoice=input("請輸入您需要的函式名稱\t\t")
# 如果反射機制找到了對應功能那麼就獲取功能函式,並執行,否則就提示沒找到,輸入main()進行測試沒有問題
if hasattr(gncs,userChoice):
fun=getattr(gncs,userChoice)
fun();
else:
print("404")
'''

'''
# 不能這樣去匯入,會導致不認識,這樣模組只會擷取匯入com 如果想要認識這種必須連結屬性為true
# str="com.lpc.Basic.kztgw3/main"

str="kztgw3/main"
gnmk,ff=str.split("/")
# 另外包也是可以進行反射的 import sys 等同於 __import__("sys")
gnmk=__import__(gnmk)
if hasattr(gnmk,ff):
fun = getattr(gnmk, ff)
fun()
else:
print("404")
'''
'''
# 如果想要認識這種必須連結屬性為true
str="com.lpc.Basic.kztgw3/main"
gnmk,ff=str.split("/")
# 另外包也是可以進行反射的 import sys 等同於 __import__("sys")
gnmk=__import__(gnmk,fromlist=True) # 如果想要認識這種必須連結屬性為true
if hasattr(gnmk,ff):
fun = getattr(gnmk, ff)
fun()
else:
print("404")
'''

'''
# 模組中特殊的變數
import com.lpc.Basic.kztgw3 as drgn

# print(drgn.__doc__) # 獲取被執行的模組頂部三引號的註釋,如果沒有為None
# print(">>>>>>>>>>>>>>>>>>>",drgn.__cached__) # 被執行的編譯的時候pyc位元組碼檔案,沒啥用,忘記吧

# print(drgn.__file__) # 被執行的py檔案所在的絕對路徑,當然如果在檔案所在目錄去執行,需要使用os.path.abspath(__file__),os.path.dirname用來獲取當前目錄的上級目錄
# print(drgn.__package__) # 包名com.lpc.Basic

# print(drgn.__dict__)

# print(drgn.__name__)
# 被執行的py檔案的名稱(含包名),他的特性是等於當前檔案的__main__,如果是在其他視窗呼叫則不等於其他檔案的__main__來達到不執行本檔案不執行的效果
# if __name__ == '__main__':
# print("如果是在當前檔案下執行,這句話就會被執行,但是如果是將本檔案匯入其他檔案,則不會被執行")

'''


'''
import sys # 和直譯器相關的

print(sys.platform) # 作業系統平臺
print("測試中》》》》》",sys.argv) # 輸出一個第一個元素是當前執行檔案路徑的列表
print("測試中》》》》》",sys.version) # 直譯器版本
print("測試中》》》》》",sys.path) # 一個直譯器相關的路徑列表,具體需要的內容自己可以去檢視
print("測試中》》》》》",sys.exit(-1)) # 引數狀態可以傳也可以不傳,程式退出



# 重點功能:進度條
def view_bar(i,total):
rate=i/total
rate_num=int(rate*100)
rate_fh=int(rate*100/5) # 獲取到百分比的數字
bl="\r%s>%d%%"%("="*rate_fh,rate_num) # \r作用是跳到最前面進行覆蓋輸出,1一個符號代表兩個進度
sys.stdout.write(bl)
# 在windows中覆蓋重新整理正常,但是Linux中看了幾個程式碼效果都一樣,不能覆蓋,這樣看起來倒是不如和shell的樣式一樣,寫成正在處理什麼,比例是多少
sys.stdout.flush()


import time
for i in range(101):
time.sleep(0.1)
view_bar(i,100)
'''

# os 模組
import os # 和系統相關的

# print(os.getcwd()) # 獲取當前執行檔案的目錄
os.chdir("/media/lipengchao/study") # 沒有返回值,用於改變當前目錄,相當於cd
# print(os.getcwd())

# print(os.curdir) # 返回當前目錄,一般需要搭配abs使用
# print(os.pardir) # 返回當前目錄的父目錄,一般需要搭配abs使用

# os.mkdir("test20181112") # 建立一個單層目錄,如果目錄存在就會報錯
# os.makedirs("test20181112/lpc/aaa") # 遞迴建立目錄,如果目錄完全存在就會報錯
# os.system("touch test20181112/lpc/aaa/lpc.txt") # 執行一個系統命令
# os.remove("test20181112/lpc/aaa/lpc.txt") # 刪除一個檔案,和rm一樣,如果為目錄則提示錯誤
# os.removedirs("test20181112/lpc/aaa") # 刪除一個目錄,如果為空則刪除遞迴到上一個目錄,如果上一個也為空,那麼也進行刪除,如果不為空則提示錯誤
# os.rmdir("test20181112/lpc/aaa") # 刪除一個空目錄,這樣就刪除了aaa,如果aaa不存在,那麼就提示錯誤
# os.rename("test20181112/lpc","test20181112/lpc111") # 這個重新命名大致相當於mv重新命名部分的功能,如果要命名的檔案不存在,那麼就提示錯誤
# print(os.stat("test20181112/")) # 以元組的方式展示指定目錄下的檔案資訊,大小,時間等等的資訊,如果寫相對路徑,必須以當前目錄為相對

# print(os.listdir(os.curdir)) # 以列表的形式列出指定目錄下的檔案,包含隱藏檔案
# print(os.name) # 字串表示當前使用平臺 nt--windows posix--linux
# print(os.sep) # 獲取作業系統的路徑分隔符,Linux下為/ windows為\
# print(os.linesep) # 實際測試了都是輸出空的,大概就是文件說的Linux下為\t\n windows為\n 沒看出有啥作用
# print(os.pathsep) # 用於分割檔案路徑的字串,Linux下為冒號: Windows下為分號;
# print(os.environ) # 以元組內防止字典的形式展示系統環境變數

'''
# os.path下的部分功能
print(os.path.abspath(os.curdir)) # 返回指定目錄的絕對路徑

# print(os.path.split("test20181112/lpc111/lpc222.txt")) # 以系統分隔符的形式將路徑分割為前面的為一個元素,最後一個分隔符的最後一個路徑為一個元素,(目錄+檔名,或者是前面目錄+最後一個分隔符後的目錄)用元組進行展示
# print(os.path.dirname("test20181112/lpc111")) # 返回最後一個系統分隔符前面的部分,最後一個分隔符的後面部分不要,其實就是上面那個分割的第一個元素
# print(os.path.basename("test20181112/lpc111")) # 返回最後一個系統分隔符後面的部分,如果以分隔符結尾則返回空split=(dirname,basename)

print(os.path.exists("test20181112/lpc111/lpc222.txt")) # 如果目錄存在則返回True,測試發現帶檔案也是可以判斷的
print(os.path.isabs("test20181112/lpc111/lpc222.txt")) # 判斷是不是絕對路徑
print(os.path.isfile("test20181112/lpc111")) # 判斷是不是一個檔案,這樣為false
print(os.path.isdir("test20181112/lpc111/lpc222.txt")) # 判斷是不是一個目錄,這樣也是False
print(os.path.join("test20181112/lpc111","test20181112/lpc111/lpc222.txt")) # 有重複的部分就直接拼接了,需要注意,這個函式比字串的拼接的好處就是自動處理作業系統的路徑分隔符
print(os.path.getatime("test20181112/lpc111")) # 返回指定檔案或者路徑下的最後【存取】時間
print(os.path.getmtime("test20181112/lpc111")) # 返回指定檔案或者路徑下的最後【修改】時間
print(os.path.getsize("test20181112/lpc111/lpc222.txt")) # 獲取指定路徑下的總大小

'''

'''
# hues 實現控制檯輸出彩色

import hues

print(hues.info(11111))
print(hues.success(22222))
'''

'''
# 加密 md5是不可逆的,如果需要判斷是否相同只能通過密文進行比較是否一致,另外Python還提供了其他加密方式,一般使用md5
# SHA1、SHA224、SHA256、SHA384、SHA512和MD5演算法等

import hashlib
passwd="李鵬超123"
md5key="lipengchao"

md5obj=hashlib.md5(bytes(md5key,encoding='utf-8')) # 建立md5物件,也可以傳入一個自己的key,防止有人猜測對應密碼,作用是在key的基礎上增加密碼進行加密
md5obj.update(bytes(passwd,encoding='utf-8')) # 如果是Python2可以直接對字串進行加密,但是Python3必須轉為位元組在進行加密
md5res=md5obj.hexdigest()

# md5res=md5obj.md5(b'12344').hexdigest() 網上也有說這兩種方式,不知道是不是沒測試好,反正沒通過,自己熟悉一種就可以了
# md5res=md5obj.new('md5',b'12344').hexdigest()
print("密碼是{passwd},加密後為{md5passwd}".format(passwd=passwd,md5passwd=md5res))
'''

# 正則表示式
import re

'''
2元字元:也就是萬用字元

. 除換行符之外的任何一個字元
^ 要求以什麼開頭
$ 要求以什麼結尾
× 匹配字元0到多次 和資料庫的基本一致
+ 匹配1到多次
? 匹配0到1次
{3} {1,5}匹配指定的次數,或者指定的次數範圍
[bc] b或者c [a-z] a到z之間的字元都可以,但是隻代表1個 表示區域內的取值範圍都是或的關係
在中括號裡面其他的符號都沒有特殊意義,只有三個符號有意義-代表區間 ^ 代表非
\代表轉義取消特殊符號的功能

\d 匹配任何十進位制的字元 相當於[0-9]
\D 匹配任何非十進位制的字元 相當於[^0-9]

\s 匹配任何空白字元 相當於[\t\n\r\f\v]
\S 匹配任何非空白字元

\w 匹配任何字母數字的字元 相當於[a-zA-Z0-9_] 除了下劃線,其他的符號都不包含
\W 匹配任何非字母數字的字元

\b 匹配一個單詞邊界,也就是指單詞和空格的位置,這個貌似不太常見,大概就是/w和/W的交界,所以其他符號也是可以的
'''

'''
str="dfdjkfaadsjladbfladfajaa"
gz1="aa" # 普通字元,這樣基本沒啥意義,主要是用來匹配萬用字元
gz2="fd." # 元字元
gz3="^a"
gz=r"I\b"
print(re.findall(gz,"I-am-a-superman")) # 以列表的形式展示字串中所有和給定字元一致的部分
res=re.match("aa","aadfdjkfdsjladfladfajaa") # 引數:規則 待處理的字串,如果匹配到返回一個物件,如果未匹配到返回None 這個是需要開頭就要符合規則,比如aa在結尾是不能匹配的
# 返回的物件有三個方法 <_sre.SRE_Match object; span=(0, 2), match='aa'>
# group() 返回被re匹配的字串,
# start() 返回匹配開始的位置
# end() 返回匹配結束的位置
# span() 返回剛才兩個值的元組
res=re.search("aa",str)
# 找到第一個符合規則的字串物件,但是不侷限於開頭,方法還是和上面的物件一樣 <_sre.SRE_Match object; span=(19, 21), match='aa'>

# 替換
res=re.sub("a.b","aaa",str,2) # 將str中符合規則的替換為aaa,最後一個引數可選,表示替換次數,不寫就是替換全部
res=re.subn("a.b","aaa",str) # 和上面的不同在於他將替換的總共次數也進行了返回 ('dfdjkfaadsjlaaafladfajaa', 1)
res=re.split("\d+","aaa1bbb2ccc3ddd4") # 這個函式相當於一個迴圈去不斷的切割符合條件的部分,特殊的就是如果最後是符合條件的分割部分,那麼列表的最後一個元素為空
print(res)
'''

# complie 先獲取比對規則的物件,然後通過規則去獲取匹配結果,這樣做的好處就是可以將經常使用的正則表示式編譯為一個物件,提高效率
# str="I am a superman !!!"
# regex=re.compile("\S*a\w*")
# res=regex.findall(str)
#
# print(res)

# 轉義字元 \ 如果需要匹配到一個 \ 這樣的話需要四個\ 因為Python轉義需要兩個代表1個,re也需要兩個進行代表1個,
# 但是這樣的話太複雜,我們使用r字首來告訴Python後面的內容已經轉義過了,這樣我們就只需要兩個 r"\\" 這樣傳遞進入re就會編譯為1個\



# 正則表示式分組 在已經匹配到的資料中進行再次提取
str="23dfdf 232ds !!!"
res=re.match("(?P<name>\d+)(\w+)",str) # 當然search這些的其他找的規則函式都是一樣的,分組的幾個方法是根據正則來說的
print(res) # 返回匹配物件
print(res.group()) # 將所有規則匹配到的字串返回 23dfdf
print(res.groups()) # 將括號內的表示式匹配到的值以元組的形式返回,多個以列表內放置元組的形式返回 ('23', 'dfdf')
print(res.groupdict()) # (?P<name>\d+) 此類格式的表示式中匹配到的值以字典的形式,key為<>中的值,value為匹配到的值,進行返回 {'name': '23'}


# res1=re.findall("(?P<name>\d+)(\w+)",str)
# print(type(res1),res1) # [('23', 'dfdf'), ('232', 'ds')]