1. 程式人生 > 實用技巧 >java中的序列化和反序列化

java中的序列化和反序列化

目錄

函式

"""
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模組

"""
正則表示式
	通過書寫一對看不懂的符號從一大堆文字中
	匹配出你想要的內容

它是一門獨立的語言 
推薦書籍:<<正則指引>>
"""