-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserialization_learning.py
More file actions
104 lines (86 loc) · 3.4 KB
/
serialization_learning.py
File metadata and controls
104 lines (86 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import pickle
sample_numdata = 255
sample_strdata = "Hello, World!"
sample_listdata = [1, 2, 3, 4, 5]
sample_dictdata = {"name": "John", "age": 30, "city": "New York"}
# Serialize sample data
""" with open("filename.pkl", mode="wb") as file:
pickle.dump(sample_numdata, file)
pickle.dump(sample_strdata, file)
pickle.dump(sample_listdata, file)
pickle.dump(sample_dictdata, file)
print(pickle.dumps(sample_numdata))
print(pickle.dumps(sample_strdata))
print(pickle.dumps(sample_listdata))
print(pickle.dumps(sample_dictdata)) """
# Protocol versions
print("\ninitial data is", sample_numdata,
"\ndumping using different protocols gives:")
for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
# print(f'ver.{protocol}', pickle.dumps(obj=sample_numdata, protocol=protocol))
pass
print(f"def.ver:",pickle.DEFAULT_PROTOCOL)
# Deseserialize data an immutable bytes object
print()
""" with open(file = "filename.pkl", mode = "rb") as file: sample_data = pickle.load(file)
print(f'loaded from the file: {sample_data}')
print(f'loaded from as binary: {pickle.loads(b'\x80\x05K\xff.')}')
"""
# Deseserialize data any byte-like object
import array
sample_array = array.array("B", [128, 5, 75, 255, 46])
pickle.loads(sample_array)
# Deseserialize recursive data structures
'''The variable cycle in the code snippet above is a dictionary
whose only key-value pair holds another dictionary,
which in turn contains a reference back to the original dictionary,
forming a cycle. '''
cycle = {}
cycle["siblings"] = {'siblings': cycle}
pickle.loads(pickle.dumps(cycle))
# The recursive list has only one element, which is a reference to itself.
recursive = []
recursive.append(recursive)
pickle.loads(pickle.dumps(recursive))
# the deeply_nested list uses half of Python’s maximum recursion limit
# to wrap lists inside one another
import sys
deeply_nested = []
dumped = pickle.dumps(deeply_nested)
pickle.loads(dumped)
### Serialize Executable Code ###
import pickle_plus
# check following codmmands in IDLE to see the messages
# impossible to serialize the whole Python module
pickle.dumps(pickle_plus)
# can’t serialize the inner functions
pickle.dumps(pickle_plus.plus_one)
# and lambda expressions imported from a module
pickle.dumps(pickle_plus.plus_two)
# as well as code objects of regular functions
pickle.dumps(pickle_plus.create_plus.__code__)
# CAN only pickle top-level functions, such as create_plus()
pickle.dumps(pickle_plus.create_plus)
# This runs on a REMOTE computer or separate IDLE session
# without [imported] the "plus" module
import pickle
pickle.loads(
b'\x80\x04\x95\x1f\x00\x00\x00\x00\x00\x00\x00\x8c'
b'\x0bpickle_plus\x94\x8c\x0bcreate_plus\x94\x93\x94.')
"""A quick and dirty way to work around this limitation of the pickle module
is to share the code in literal form for the exec() function to execute later"""
import importlib
import inspect
def get_module_source(module_name: str) -> str:
module = importlib.import_module(name = module_name)
return inspect.getsource(module)
source_code = get_module_source("pickle_plus")
print(source_code)
exec(source_code)
plus_one(5); plus_two(5)
# use DILL instead of pickle, to conveniently narrow down the source code extracted from a module
import dill.source
from pickle_plus import plus_two
source_code_byDill = dill.source.getsource(plus_two)
# only got the source code of the plus_two() callable
exec(source_code); plus_two(5)