java中的序列化和反序列化
阿新 • • 發佈:2020-07-25
目錄
函式
""" 1.什麼是函式 函式其實就是工具 如果沒有函式就類似於每一次要使用錘子的時候 需要自己原地起鍋燒火打造 2.為什麼要有函式 為了節省人力、減少程式碼冗餘 3.如何定義及使用函式 """ # 函式的基本格式 """ def func(引數1、引數2...): '''函式的註釋''' 函式體程式碼(就是真正的功能) return 函式的返回值 1.def是定義函式的關鍵字 2.func是函式名 指向記憶體空間中的函式體程式碼 函式名的命名規範跟變數名一致 3.引數1、引數2在呼叫函式的時候可能需要傳入的外部資料 4.函式的註釋 用來解釋函式的功能及使用的注意事項等等 5.函式體程式碼 實現該函式功能的實際程式碼 6.return返回值 在呼叫完函式之後 得到的結果 """
函式的返回值
# 關鍵字return def index(): name = 'jason' # return 123 # return 123,1,2,3,4,5,6 return 123,'jason',11.11,{'username':'jason'} print('會不會列印我') # 1 函式沒有return 預設返回None # res = index() # print(res) # None # 2 就算有return後面如果什麼都沒有 還是返回None # res = index() # print(res) # None # 3 return後面跟什麼 函式就返回什麼 # res = index() # print(res) # 123 # 3.1 如果後面有多個數據 自動組織成元組返回 # print(res) # (123, 1, 2, 3, 4, 5, 6) # 3.2 支援多個並且可以是任意資料型別 # print(res) # (123, 'jason', 11.11, {'username': 'jason'}) # ps:如果一個函式有多個返回值 那麼我們很有可能會直接使用解壓賦值 # a,b,c,d = index() # print(a,b,c,d) """ return可以返回值 並且在函式體內部一旦遇到return 函式會立刻結束 """
函式的引數分類
def index(x,y): # x和y就是形式引數 print(x,y) index(1,2) # 1和2就是實際引數 將1賦值給x 將2賦值給y """ 函式的引數分為兩大類 形式引數 函式在定義階段括號內指定的變數名叫形式引數 簡稱為形參 實際引數 函式在呼叫階段括號內指定的資料 叫實際引數 簡稱為實參 兩者之間的關係其實就相當於 形參是變數名 實參是變數值 傳參呼叫函式其實就是給形參賦值 """
函式的引數
# 位置引數
# def my_max(x,y):
# print(x,y)
# my_max(1,2) # 1 2
# my_max(1) # 少傳一個不行
# my_max(1,2,3) # 多傳一個也不行
# 預設引數
# 不傳有預設的 傳了就用自己的
# def register(name,gender='male'):
# print(name,gender)
# register('jason','male')
# register('jason','male')
# register('jason','male')
# register('jason','male')
# register('jason','male')
# register('jason','male')
# register('jason','male')
# register('frank','female')
# register('haoda','others')
# register('jason')
# register('jason')
# register('jason')
# register('jason')
# register('shanshan','female')
# 關鍵字引數
# def register(name,gender):
# print(name,gender)
# register(1,2)
# register(2,1)
# register(gender=2,name=1) # 指名道姓的傳 打破位置限制
# 混合使用
# register(gender=2,1) # 位置引數不能出現在關鍵字引數的後面
# register(1,gender=2)
# register(1,name=2) # 在一次呼叫中 一個形參不能重複的賦值
"""
引數的順序
越短的越靠前
越長的越靠後
"""
# 可變長引數
def index(x,*a,**k):
print(x,a,k)
# 函式無論接收多少引數都能夠正常執行
# index(1,2) # 1 (2,)
# index(1,2,3,4,5,6,7,8,9,0) # 1 (2, 3, 4, 5, 6, 7, 8, 9, 0)
# index(1) # 1 ()
# index(x=1,y=2,z=3) # 1 () {'y': 2, 'z': 3}
index(1,2,3,4,5,y=2,z=3) # 1 (2, 3, 4, 5) {'y': 2, 'z': 3}
"""
*號在形參中 用來接收多餘的位置引數
組織成元組的形式賦值給後面的變數名
**號在形參中 用來接收多餘的關鍵字引數
組織成字典的形式賦值給後面的變數名
雖然*和**後面的變數名沒有固定的值,但是一般情況下我們會預設寫成
*args
**kwargs
"""
def login(*args,**kwargs):
print(123)
login(1,2,3,4,5,6,7,7)
login(x=1,y=2,z=3)
login(1,2,3,4,5,6,7,7,x=1,y=2,z=3)
"""
*號在實參中
能夠將列表、字串打散 將打散成位置引數
**號在實參中
能夠將字典打散成關鍵字引數
"""
def index(*args,**kwargs):
print('args:',args)
print('kwargs:',kwargs)
l = [1,2,3,4,5,6,7,8,9,0]
d = {'username':"jason",'password':123}
# index(l) # args: ([1, 2, 3, 4, 5, 6, 7, 8, 9, 0],) index(1,2,3,4,5,6,7,8,9,0)
# index(*l) # args: (1, 2, 3, 4, 5, 6, 7, 8, 9, 0)
# index(d) # args: ({'username': 'jason', 'password': 123},)
index(**d) # kwargs: {'username': 'jason', 'password': 123}
index(username='jason',password=123)
函式物件
# def index():
# print('from index')
# 1 函式名可以被當做變數名賦值給其他變數
# print(index)
# f = index
# # print(f)
# # index()
# f()
# 2 函式名可以當做函式的引數傳入
# def index():
# print('from index')
# name = 'jason'
# def func(x):
# print(x)
# x()
# func(index)
# 3 函式名還可以當做函式的返回值(******)
# def bar():
# print('from bar')
#
# def index():
# print('from index')
# return bar
# res = index()
# res() # bar()
# 4 函式名還可以作為容器型別(能夠儲存多個元素的資料型別)的元素
def bar():
print('from bar')
l = [1,2,3,4,5,6,bar]
l[-1]()
函式的巢狀定義、呼叫
def index():
print('from index')
def inner():
print('from inner')
# return inner
inner()
res = index()
名稱空間與作用域
"""
名稱空間
name = 'jason' 名稱空間其實就是用來儲存名字和值繫結關係的地方
內建名稱空間
python直譯器啟動之後就會自動建立的名稱空間
這個裡面存放的是python直譯器事先給你準備好的一些名字
len、max、min...
全域性名稱空間
在檔案級別定義的
name = 'jason'
if 1:
age = 18
while True:
gender = 'male'
def index():
pass
區域性名稱空間
在函式體內部定義的
呼叫函式的時候建立 函式結束之後銷燬
"""
# 名稱空間的查詢順序
"""
你要先確定你當前在哪
"""
# print(len) # 內建
# len = '有點餓了'
def index():
# len = '我也很餓'
print(len)
# print(len)
index()
"""
內建 <== 全域性 <== 區域性
1.如果你當前在全域性的話
這個時候查詢順序是
全域性 >>> 內建
2.如果你當前在區域性
這個時候查詢順序是
區域性 >>> 全域性 >>> 內建
"""
# 作用域
"""
區域性作用域
區域性名稱空間
全域性作用域
內建、全域性名稱空間
"""
# name = 'jason'
# def index():
# name = 'frank' # 自己在自己的區域性名稱空間中建立了一個名字name
# index()
# print(name)
# 區域性修改全域性
# name = 'jason'
# def index():
# global name # 宣告我要修改全局裡面的name而不是建立
# name = 'frank' # 自己在自己的區域性名稱空間中建立了一個名字name
# index()
# print(name)
# 區域性修改區域性
def func():
name = 'haoda'
def index():
name = 'jason'
def inner():
nonlocal name
name = 'egon'
# print(name)
inner()
print(name)
index()
func()
小補充
1.交叉賦值
m = 1
n = 2
# m = n
# n = m
# print(m,n)
# tmp = m
# m = n
# n = tmp
# print(m,n)
# 交叉賦值
m, n = n,m
print(m,n)
2.pass用法
def register():
pass
def register1():
...
裝飾器
"""
裝飾器
在不改變被裝飾物件(函式)
1.呼叫方式
2.原始碼
的基礎之上給被裝飾物件(函式)新增額外的功能
"""
# 提前書寫裝飾器的固定程式碼
def outer(func):
def inner(*args,**kwargs):
print('在執行被裝飾函式之前你可以新增的額外操作')
res = func(*args,**kwargs)
print('在執行被裝飾函式之後你可以新增的額外操作')
return res
return inner
@outer # index = outer(index)
def index():
print('from index')
# index()
print(index)
# 你們只需要熟悉無參裝飾器即可
# 有參裝飾器
def login_auth(x):
def outer(func):
def inner(*args,**kwargs):
print('在執行被裝飾函式之前你可以新增的額外操作')
res = func(*args,**kwargs)
print('在執行被裝飾函式之後你可以新增的額外操作')
return res
return inner
return outer
@login_auth(123)
def home():
pass
遞迴
"""
遞迴
函式在呼叫階段 自己直接或者間接的又呼叫了自己
"""
def index():
print('from index')
index()
index()
import sys
print(sys.getrecursionlimit())
"""
不能無限制的遞迴,沒有實際意義
1.遞迴的次數必須是有限的
2.每一次遞迴都要比上一次複雜度更低
包含兩個過程
遞推
回溯
"""
age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 18
def get_age(num):
if num == 1:
return 18
return get_age(num-1) + 2
# 遞迴案例
l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,]]]]]]]]]]]
def get_value(l):
for i in l:
if not isinstance(i,list):
print(i)
else:
get_value(i)
get_value(l)
二分法
"""
演算法
其實就是解決問題的高效率的方法
"""
二分法
"""
二分法
參考的資料必須有大小順序
"""
num_list = [13,15,17,23,55,78,98,123,234,345,453,567,657,713,890]
target_num = 23
def b_search(num_list,target_num):
# 程式碼優化 值不存在的情況
if len(num_list) == 0:
print('要找的數字不在這個列表內')
return
# 先獲取中間索引值
middle_index = len(num_list) // 2
# 判斷要找的數字於中間索引對應的值孰大孰小
if target_num > num_list[middle_index]:
# 擷取右半邊大的部分
num_list = num_list[middle_index+1:]
search(num_list,target_num)
elif target < num_list[middle_index]:
# 擷取左半邊小的部分
num_list = num_list[0:middle_index]
search(num_list,target_num)
else:
print('find it!')
三元表示式、生成器
# 判斷兩個數的最大值
# def index(x,y):
# # if x > y:
# # print(x)
# # else:
# # print(y)
# # 三元表示式
# return x if x > y else y
"""
三元表示式只適用於兩選一的情況
x if x > y else y
如果if後面的條件成立那麼返回if前面的值
如果條件不成立那麼返回else後面的值
"""
# x = 1
# y = 10
# res = x if x > y else (y if y > x else 666)
# print(res)
# name = input('username>>>:')
# res = 'NB' if name == 'jason' else '垃圾'
# print(res)
# 列表生成式
# l = ['jason','frank','tony','tom','haoda']
# # 以前的套路
# # new_l = []
# # for name in l:
# # new_l.append(name+'_NB')
# # print(new_l)
#
#
# # 列表生成式
# # res = [name+'_DSB' for name in l]
# res = [name+'_DSB' for name in l if name=='jason'] # ['jason_DSB']
# print(res)
# 生成器表示式
# l = ['jason','frank','tony','tom','haoda']
# res = (name+'_DSB' for name in l) # <generator object <genexpr> at 0x000002D5F0F26048>
# for i in res:
# print(i)
"""
生成器能夠節省記憶體 是我們程式優化階段需要考慮的事情
"""
匿名函式
"""
沒有名字的函式
一般情況下都是結合內建函式一起使用的
"""
res = lambda x,y:x+y
ret = res(1,2)
print(ret)
def index(x,y):
return x + y
salaries = {
'egon':30000,
'jason':888888888,
'nick':2000,
'tank':100
}
# print(max(salaries))
# """
# A-Z 65-90
# a-z 97-122
# """
def index(name):
return salaries[name]
# res = max(salaries,key=index)
res = max(salaries,key=lambda name:salaries[name])
print(res)
模組
"""
其實就是一系列功能的集合體
1.內建模組
2.第三方模組
3.自定義模組
"""
# 匯入模組的方式
1.import...
2.from...import...
# 起別名
import mymd as md
md.index()
3.from mymd import *
index()
print(name)
# 如何匯入第三方模組
1.利用pip3下載對應的模組
2.然後再利用上述import或者from import匯入即可
常用模組
# import mymd
"""
將mymd裡面所有的資源匯入到當前檔案
匯入模組其實就是從上往下執行該模組程式碼
重複匯入一個模組 只會生效一次
其餘的語句不會起作用
"""
# print(mymd.index())
# print(mymd.name)
# from mymd import name
# import mymd as md
# md.index()
# from mymd import *
# index()
# print(name)
# 時間模組 time datetime
# import time
# print(time.time()) # 1595666567.451175
# time.sleep(3)
# print('寶貝你醒啦 麼麼噠')
# print(time.strftime('%Y-%m-%d'))
# print(time.strftime('%Y-%m-%d %X'))
# print(time.strftime('%Y-%m-%d %H:%M:%S'))
import datetime
# print(datetime.datetime.now())
# print(datetime.date.today())
"""
2020-07-25 16:47:24.534835
2020-07-25
"""
# timedelta物件
# 可以對時間進行運算操作
import datetime
# 獲得本地日期 年月日
# tday = datetime.date.today()
# 定義操作時間 day=7 也就是可以對另一個時間物件加7天或者減少7點
# tdelta = datetime.timedelta(days=7)
# 列印今天的日期
# print('今天的日期:{}'.format(tday))
# 列印七天後的日期
# print('從今天向後推7天:{}'.format(tday + tdelta))
# 總結:日期物件與timedelta之間的關係
"""
日期物件 = 日期物件 +/- timedelta物件
timedelta物件 = 日期物件 +/- 日期物件
"""
# 小練習 計算舉例今年過生日還有多少天
# birthday = datetime.date(2000, 1, 21)
# now_date = datetime.date.today()
# days = birthday - now_date
# print('生日:{}'.format(birthday))
# print('今天的日期:{}'.format(now_date))
# print('距離生日還有{}天'.format(days))
# 隨機模組random
import random
# print(random.randint(1,6)) # 1到6隨機的整數
# print(random.random()) # 0到1之間的小數
# l = [1,2,3,4,5,6,7,8,9]
# random.shuffle(l)
# print(l)
# l = ['1號技師','2號技師','3號技師','4號技師','5號技師']
# res = random.choice(l)
# print(res)
# 搜狗筆試題
# 生成五位數的隨機驗證碼 要求
# 每一位都是可以是數字、小寫字母、大寫字母
code = ''
for i in range(5):
# 每次都隨機產生一個數字
random_int = str(random.randint(0,9))
# 每次都隨機產生一個小寫字母
random_lower = chr(random.randint(97,122))
# 每次都隨機產生一個大寫字母
random_upper = chr(random.randint(65, 90))
# 三者選一個
temp = random.choice([random_int,random_lower,random_upper])
# 拼接
code += temp
print(code)
os與sys
os跟作業系統打交道的
sys是跟直譯器打交道的
import os
# os.path.join()
res = os.path.getsize(r'D:\ln_day02')
print(res)
"""
拼接路徑的時候 不同的作業系統分隔符是不一樣
"""
import sys
print(sys.getrecursionlimit()) # 1000
序列化模組
"""
json格式資料
1、不同語言之間的資料互動
2、其實就是一堆字串
"""
import json
d = {'username':'jason','password':123}
# res = json.dumps(d) # 將資料轉成字串的過程 就叫序列化
# print(res,type(res)) # {"username": "jason", "password": 123} <class 'str'>
#
# res1 = json.loads(res) # 將json格式的字串轉換成程式設計裡面的資料型別 反序列化
# print(res1,type(res1)) # {'username': 'jason', 'password': 123} <class 'dict'>
"""
encode
decode
"""
# with open('a.txt','w',encoding='utf-8') as f:
# json.dump(d,f)
with open('a.txt','r',encoding='utf-8') as f:
res = json.load(f)
print(res,type(res))
加密模組
# 加密模組
# import hashlib
# md5 = hashlib.md5()
# md5.update(b'123') # 資料必須是bytes型別
# # md5.update(b'h') # 資料必須是bytes型別
# # md5.update(b'ell') # 資料必須是bytes型別
# # md5.update(b'o world') # 資料必須是bytes型別
# res = md5.hexdigest()
# print(res) # 5eb63bbbe01eeed093cb22bb8f5acdc3
"""
update無論你是一次性傳入還是分批次傳入
只要傳入的資料是一樣的 那麼結果肯定一樣
"""
"""
123 sdksjdjasljd
132 dsdsadasddsad
hello dsakldjsdjadksad
"""
# 加鹽
# import hashlib
# md5 = hashlib.md5()
# md5.update(b'12321sadsald123kjasdkjal')
# md5.update(b'123') # 資料必須是bytes型別
# # md5.update(b'h') # 資料必須是bytes型別
# # md5.update(b'ell') # 資料必須是bytes型別
# # md5.update(b'o world') # 資料必須是bytes型別
# res = md5.hexdigest()
# print(res) # 5eb63bbbe01eeed093cb22bb8f5acdc3
# 動態加鹽
# import hashlib
# md5 = hashlib.md5()
# md5.update(b'')
# md5.update(b'123') # 資料必須是bytes型別
# # md5.update(b'h') # 資料必須是bytes型別
# # md5.update(b'ell') # 資料必須是bytes型別
# # md5.update(b'o world') # 資料必須是bytes型別
# res = md5.hexdigest()
# print(res) # 5eb63bbbe01eeed093cb22bb8f5acdc3
日誌模組
https://www.cnblogs.com/Dominic-Ji/articles/11109067.html
re模組
"""
正則表示式
通過書寫一對看不懂的符號從一大堆文字中
匹配出你想要的內容
它是一門獨立的語言
推薦書籍:<<正則指引>>
"""