Object-oriented-python-serialization
オブジェクト指向Python-オブジェクトのシリアル化
データストレージのコンテキストでは、シリアル化とは、データ構造またはオブジェクトの状態を、ファイルやメモリバッファーに格納できる形式に変換したり、後で送信および再構築したりするプロセスです。
シリアル化では、オブジェクトを保存可能な形式に変換して、後でシリアル化を解除し、シリアル化された形式から元のオブジェクトを再作成できるようにします。
ピクルス
酸洗とは、Pythonオブジェクト階層をバイトストリーム(通常は人間が読み取れない形式)に変換してファイルに書き込むプロセスです。これは、シリアル化とも呼ばれます。 ピックル解除は逆の操作であり、バイトストリームは変換されて動作するPythonオブジェクト階層に戻ります。
Pickleは、オブジェクトを保存する操作上最も簡単な方法です。 Python Pickleモジュールは、オブジェクトを特別なストレージ形式で直接保存するオブジェクト指向の方法です。
何ができますか?
- Pickleは、辞書とリストを非常に簡単に保存および再現できます。
- オブジェクトの属性を保存し、同じ状態に復元します。
ピクルスにできないことは何ですか?
- オブジェクトコードは保存されません。 属性値のみです。
- ファイルハンドルまたは接続ソケットを保存できません。
要するに、pickleは、変数がリストやクラスなどである可能性のあるファイルにデータ変数を保存したり、ファイルからデータ変数を取得したりする方法です。
何かをピクルスするには、あなたがする必要があります-
- 輸入ピクルス
- 次のような変数をファイルに書き込みます
pickle.dump(mystring, outfile, protocol),
3番目の引数のプロトコルはオプションです。
インポートピクルス
次のような変数をファイルに書き込みます
myString = pickle.load(inputfile)
方法
pickleインターフェースには4つの異なる方法があります。
- * dump()*-dump()メソッドは、開いているファイル(ファイルのようなオブジェクト)にシリアル化します。
- * dumps()*-文字列にシリアル化
- * load()*-オープンライクなオブジェクトからデシリアライズします。
- * loads()*-文字列から逆シリアル化します。
上記の手順に基づいて、以下は「酸洗い」の例です。
出力
My Cat pussy is White and has 4 legs
Would you like to see her pickled? Here she is!
b'\x80\x03c__main__\nCat\nq\x00)\x81q\x01}q\x02(X\x0e\x00\x00\x00number_of_legsq\x03K\x04X\x05\x00\x00\x00colorq\x04X\x05\x00\x00\x00Whiteq\x05ub.'
したがって、上記の例では、Catクラスのインスタンスを作成し、それをピクルスして、「Cat」インスタンスを単純なバイト配列に変換しました。
これにより、バイト配列をバイナリファイルまたはデータベースフィールドに簡単に保存し、後でストレージサポートから元の形式に復元することができます。
また、pickleオブジェクトを使用してファイルを作成する場合は、(dumps *()*メソッドの代わりに)dump()メソッドを使用して、開いているバイナリファイルも渡すことができ、pickleの結果はファイルに自動的に保存されます。
[….]
binary_file = open(my_pickled_Pussy.bin', mode='wb')
my_pickled_Pussy = pickle.dump(Pussy, binary_file)
binary_file.close()
ピックル解除
バイナリ配列を受け取り、それをオブジェクト階層に変換するプロセスは、ピッキング解除と呼ばれます。
ピクル解除プロセスは、pickleモジュールのload()関数を使用して行われ、単純なバイト配列から完全なオブジェクト階層を返します。
前の例で関数loadを使用してみましょう。
出力
MeOw is black
Pussy is white
JSON
JSON(JavaScript Object Notation)は、Python標準ライブラリの一部であり、軽量のデータ交換形式です。 人間にとって読み書きは簡単です。 解析と生成は簡単です。
JSONはシンプルであるため、JSONはデータを保存および交換する方法であり、JSON構文を介して実現され、多くのWebアプリケーションで使用されています。 人間が読める形式であるため、APIを使用する際の有効性に加えて、これがデータ転送で使用する理由の1つである可能性があります。
JSON形式のデータの例は次のとおりです-
{"EmployID": 40203, "Name": "Zack", "Age":54, "isEmployed": True}
Pythonを使用すると、Jsonファイルを簡単に操作できます。 この目的で使用されるモジュールはJSONモジュールです。 このモジュールは、Pythonインストールに含まれる(組み込まれる)必要があります。
Python辞書をJSONに変換してテキストファイルに書き込む方法を見てみましょう。
JSONからPython
JSONの読み取りとは、JSONをPython値(オブジェクト)に変換することを意味します。 jsonライブラリは、JSONをPythonの辞書またはリストに解析します。 それを行うには、次のように、loads()関数(文字列からの読み込み)を使用します-
出力
以下はjsonファイルのサンプルです。
data1.json
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
上記のコンテンツ(Data1.json)は、従来の辞書のように見えます。 pickleを使用してこのファイルを保存できますが、その出力は人間が読める形式ではありません。
JSON(Java Script Object Notification)は非常にシンプルな形式であり、それが人気の理由の1つです。 それでは、以下のプログラムを通してjsonの出力を見てみましょう。
Java Script Object Notification
出力
上記では、読み取り用にjsonファイル(data1.json)を開き、ファイルハンドラーを取得し、json.loadに渡してオブジェクトを取得します。 jsonファイルと同じ、オブジェクトの出力を印刷しようとしています。 オブジェクトのタイプは辞書ですが、Pythonオブジェクトとして出力されます。 このピクルスを見たように、jsonへの書き込みは簡単です。 上記でjsonファイルをロードし、別のキーと値のペアを追加して、同じjsonファイルに書き戻します。 data1.jsonを見ると、見た目が異なります。 以前と同じ形式ではありません。
出力が同じように見えるように(人間が読める形式)、プログラムの最後の行にいくつかの引数を追加し、
json.dump(conf, fh, indent = 4, separators = (‘,’, ‘: ‘))
同様に、pickleのように、ダンプを使用して文字列を出力し、ロードを使用してロードできます。 以下はその例です。
YAML
YAMLは、すべてのプログラミング言語にとって最も人間に優しいデータシリアル化標準である可能性があります。
Python yamlモジュールはpyamlと呼ばれます
YAMLはJSONの代替です-
- 人間が読めるコード-YAMLは最も人間が読める形式なので、そのトップページのコンテンツでさえYAMLで表示されるため、この点がわかります。
- コンパクトコード-YAMLでは、空白インデントを使用して括弧ではなく構造を示します。
- リレーショナルデータの構文-内部参照には、アンカー(&)とエイリアス(*)を使用します。
- 広く使用されている領域の1つは、データ構造の表示/編集用です-例えば、設定ファイル、デバッグ中のダンプ、ドキュメントヘッダー。
YAMLのインストール
yamlは組み込みモジュールではないため、手動でインストールする必要があります。 Windowsマシンにyamlをインストールする最良の方法は、pipを使用することです。 Windowsターミナルで以下のコマンドを実行して、yamlをインストールします。
pip install pyaml (Windows machine)
sudo pip install pyaml (*nix and Mac)
上記のコマンドを実行すると、現在の最新バージョンに基づいて、画面に次のようなものが表示されます。
Collecting pyaml
Using cached pyaml-17.12.1-py2.py3-none-any.whl
Collecting PyYAML (from pyaml)
Using cached PyYAML-3.12.tar.gz
Installing collected packages: PyYAML, pyaml
Running setup.py install for PyYAML ... done
Successfully installed PyYAML-3.12 pyaml-17.12.1
テストするには、Pythonシェルに移動してyamlモジュールをインポートし、yamlをインポートします。エラーが見つからない場合は、インストールが成功したと言えます。
pyamlをインストールした後、以下のコードを見てみましょう。
script_yaml1.py
上記では、3つの異なるデータ構造、辞書、リスト、およびタプルを作成しました。 各構造で、yaml.dumpを実行します。 重要なポイントは、出力が画面にどのように表示されるかです。
出力
辞書の出力はきれいに見えます。 キー:値。
異なるオブジェクトを分離するための空白。
リストはダッシュ(-)で表記されます
タプルは、最初に!! Python/tupleで示され、次にリストと同じ形式で示されます。
yamlファイルをロードする
だから、私は1つのyamlファイルを持っているとしましょう
---
# An employee record
name: Raagvendra Joshi
job: Developer
skill: Oracle
employed: True
foods:
- Apple
- Orange
- Strawberry
- Mango
languages:
Oracle: Elite
power_builder: Elite
Full Stack Developer: Lame
education:
4 GCSEs
3 A-Levels
MCA in something called com
では、yaml.load関数を使用してこのyamlファイルを読み込むコードを作成しましょう。 以下は同じコードです。
出力はそれほど読みにくいように見えるため、最後にjsonを使用して出力を説明します。 取得した出力と実際のyamlファイルを比較します。
出力
ソフトウェア開発の最も重要な側面の1つは、デバッグです。 このセクションでは、ビルトインデバッガーまたはサードパーティのデバッガーを使用したPythonデバッグのさまざまな方法について説明します。
PDB – Pythonデバッガー
モジュールPDBは、ブレークポイントの設定をサポートしています。 ブレークポイントは、プログラムの意図的な一時停止であり、プログラムの状態に関する詳細情報を取得できます。
ブレークポイントを設定するには、次の行を挿入します
pdb.set_trace()
例
pdb_example1.py
import pdb
x = 9
y = 7
pdb.set_trace()
total = x + y
pdb.set_trace()
このプログラムにいくつかのブレークポイントを挿入しました。 プログラムは各ブレークポイントで停止します(pdb.set_trace())。 変数の内容を表示するには、変数名を入力するだけです。
c:\Python\Python361>Python pdb_example1.py
> c:\Python\Python361\pdb_example1.py(8)<module>()
-> total = x + y
(Pdb) x
9
(Pdb) y
7
(Pdb) total
*** NameError: name 'total' is not defined
(Pdb)
cを押すか、次のブレークポイントまでプログラムの実行を続けます。
(Pdb) c
--Return--
> c:\Python\Python361\pdb_example1.py(8)<module>()->None
-> total = x + y
(Pdb) total
16
最終的には、はるかに大きなプログラム(サブルーチンを使用するプログラム)をデバッグする必要があります。 そして、時々、あなたが見つけようとしている問題はサブルーチンの中にあるでしょう。 次のプログラムを考えてください。
import pdb
def squar(x, y):
out_squared = x^2 + y^2
return out_squared
if __name__ == "__main__":
#pdb.set_trace()
print (squar(4, 5))
上記のプログラムを実行すると、
c:\Python\Python361>Python pdb_example2.py
> c:\Python\Python361\pdb_example2.py(10)<module>()
-> print (squar(4, 5))
(Pdb)
?*を使用してヘルプを取得できますが、矢印は実行しようとしている行を示しています。 この時点で、sを押して *s を押すと、その行にステップインできます。
(Pdb) s
--Call--
>c:\Python\Python361\pdb_example2.py(3)squar()
-> def squar(x, y):
これは関数の呼び出しです。 あなたがあなたのコードのどこにいるかの概要が必要な場合は、lを試してください-
(Pdb) l
1 import pdb
2
3 def squar(x, y):
4 -> out_squared = x^2 + y^2
5
6 return out_squared
7
8 if __name__ == "__main__":
9 pdb.set_trace()
10 print (squar(4, 5))
[EOF]
(Pdb)
nを押すと、次の行に進むことができます。 この時点で、out_squaredメソッド内にあり、関数.i.e内で宣言された変数にアクセスできます。 xとy
(Pdb) x
4
(Pdb) y
5
(Pdb) x^2
6
(Pdb) y^2
7
(Pdb) x**2
16
(Pdb) y**2
25
(Pdb)
そのため、^演算子は望んだものではなく、代わりに**演算子を使用して平方を行う必要があることがわかります。
これにより、関数/メソッド内でプログラムをデバッグできます。
ロギング
ロギングモジュールは、Pythonバージョン2.3以降、Pythonの標準ライブラリの一部となっています。 組み込みモジュールなので、すべてのPythonモジュールがロギングに参加できるため、アプリケーションログには、サードパーティモジュールからのメッセージと統合された独自のメッセージを含めることができます。 多くの柔軟性と機能を提供します。
ロギングの利点
- 診断ログ-アプリケーションの操作に関連するイベントを記録します。
- 監査ログ-ビジネス分析のためにイベントを記録します。
メッセージは「重大度」レベルで書き込まれ、ログに記録されます&minu
- * DEBUG(debug())*-開発用の診断メッセージ。
- * INFO(info())*-標準の「進捗」メッセージ。
- 警告(warning())-重大ではない問題を検出しました。
- * ERROR(error())*-重大なエラーが発生しました。
- * CRITICAL(critical())*-通常、致命的なエラー(プログラムが停止します)。
以下の簡単なプログラムを見てみましょう。
import logging
logging.basicConfig(level=logging.INFO)
logging.debug('this message will be ignored') # This will not print
logging.info('This should be logged') # it'll print
logging.warning('And this, too') # It'll print
上記では、重大度レベルでメッセージを記録しています。 最初にモジュールをインポートし、basicConfigを呼び出してログレベルを設定します。 上記で設定したレベルはINFOです。 次に、デバッグステートメント、情報ステートメント、警告ステートメントの3つの異なるステートメントがあります。
logging1.pyの出力
INFO:root:This should be logged
WARNING:root:And this, too
infoステートメントはdebugステートメントの下にあるため、デバッグメッセージを表示できません。 Outputターミナルでもデバッグステートメントを取得するには、basicConfigレベルのみを変更する必要があります。
logging.basicConfig(level = logging.DEBUG)
そして、出力で見ることができます、
DEBUG:root:this message will be ignored
INFO:root:This should be logged
WARNING:root:And this, too
また、デフォルトの動作では、ログレベルを設定しない場合は警告になります。 上記のプログラムの2行目をコメントアウトして、コードを実行します。
#logging.basicConfig(level = logging.DEBUG)
出力
WARNING:root:And this, too
ロギングレベルに組み込まれたPythonは、実際には整数です。
>>> import logging
>>>
>>> logging.DEBUG
10
>>> logging.CRITICAL
50
>>> logging.WARNING
30
>>> logging.INFO
20
>>> logging.ERROR
40
>>>
ログメッセージをファイルに保存することもできます。
logging.basicConfig(level = logging.DEBUG, filename = 'logging.log')
これで、すべてのログメッセージは、画面ではなく現在の作業ディレクトリのファイル(logging.log)に送信されます。 これは、受け取ったメッセージの事後分析を行うことができるため、はるかに優れたアプローチです。
ログメッセージで日付スタンプを設定することもできます。
logging.basicConfig(level=logging.DEBUG, format = '%(asctime)s %(levelname)s:%(message)s')
出力は次のようになります。
2018-03-08 19:30:00,066 DEBUG:this message will be ignored
2018-03-08 19:30:00,176 INFO:This should be logged
2018-03-08 19:30:00,201 WARNING:And this, too
ベンチマーク
ベンチマークまたはプロファイリングは、基本的に、コードの実行速度とボトルネックの場所をテストすることです。 これを行う主な理由は、最適化のためです。
計時
Pythonには、timeitと呼ばれる組み込みモジュールが付属しています。 これを使用して、小さなコードスニペットを計測できます。 timeitモジュールはプラットフォーム固有の時間関数を使用するため、可能な限り最も正確なタイミングを取得できます。
そのため、それぞれのコードの2つの出荷を比較し、スクリプトを最適化してパフォーマンスを向上させることができます。
timeitモジュールにはコマンドラインインターフェイスがありますが、インポートすることもできます。
スクリプトを呼び出すには2つの方法があります。 最初にスクリプトを使用してみましょう。そのためには以下のコードを実行し、出力を確認します。
import timeit
print ( 'by index: ', timeit.timeit(stmt = "mydict['c']", setup = "mydict = {'a':5, 'b':10, 'c':15}", number = 1000000))
print ( 'by get: ', timeit.timeit(stmt = 'mydict.get("c")', setup = 'mydict = {"a":5, "b":10, "c":15}', number = 1000000))
出力
by index: 0.1809192126703489
by get: 0.6088525265034692
上記では、2つの異なる方法を使用しています。 添え字によって、辞書のキー値にアクセスします。 非常に小さなデータに対しては速すぎるため、ステートメントを100万回実行します。 これで、getよりもはるかに高速にインデックスアクセスを確認できます。 コードを複数回実行することができ、理解を深めるために実行時間にわずかなばらつきがあります。
別の方法は、コマンドラインで上記のテストを実行することです。 やってみましょう、
c:\Python\Python361>Python -m timeit -n 1000000 -s "mydict = {'a': 5, 'b':10, 'c':15}" "mydict['c']"
1000000 loops, best of 3: 0.187 usec per loop
c:\Python\Python361>Python -m timeit -n 1000000 -s "mydict = {'a': 5, 'b':10, 'c':15}" "mydict.get('c')"
1000000 loops, best of 3: 0.659 usec per loop
上記の出力は、システムのハードウェアと、システムで現在実行されているすべてのアプリケーションによって異なります。
関数を呼び出す場合は、以下でtimeitモジュールを使用できます。 テストする関数内に複数のステートメントを追加できるため。
import timeit
def testme(this_dict, key):
return this_dict[key]
print (timeit.timeit("testme(mydict, key)", setup = "from __main__ import testme; mydict = {'a':9, 'b':18, 'c':27}; key = 'c'", number = 1000000))
出力
0.7713474590139164