オブジェクト指向Python-オブジェクトのシリアル化
データストレージのコンテキストでは、シリアル化とは、データ構造またはオブジェクトの状態を、保存(ファイルやメモリバッファなど)または送信して後で再構築できる形式に変換するプロセスです。
シリアル化では、オブジェクトは保存可能な形式に変換され、後で逆シリアル化して、シリアル化された形式から元のオブジェクトを再作成できるようになります。
ピクルス
Picklingは、Pythonオブジェクト階層がバイトストリーム(通常は人間が読めない)に変換されてファイルに書き込まれるプロセスです。これはシリアル化とも呼ばれます。選択解除は逆の操作であり、バイトストリームが動作中のPythonオブジェクト階層に変換されます。
Pickleは、オブジェクトを格納するための操作上最も簡単な方法です。Python Pickleモジュールは、オブジェクトを特別なストレージ形式で直接格納するためのオブジェクト指向の方法です。
それは何ができますか?
- Pickleは、辞書やリストを非常に簡単に保存および複製できます。
- オブジェクト属性を格納し、それらを同じ状態に復元します。
ピクルスができないことは何ですか?
- オブジェクトコードは保存されません。それだけが属性値です。
- ファイルハンドルや接続ソケットは保存できません。
要するに、pickle化は、変数がリストやクラスなどであるファイルにデータ変数を格納したり、ファイルからデータ変数を取得したりする方法であると言えます。
何かを漬けるにはあなたがしなければならない-
- ピクルスをインポート
- 次のような変数をファイルに書き込みます
pickle.dump(mystring, outfile, protocol),
ここで、3番目の引数プロトコルはオプションです。何かを選択解除するには、次のことを行う必要があります。
ピクルスをインポートする
次のような変数をファイルに書き込みます
myString = pickle.load(inputfile)
メソッド
ピクルスインターフェースは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()メソッドを使用して、開いているバイナリファイルも渡すことができます。
[….]
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構文を介して実行され、多くの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()関数(文字列からのロード)を使用します。
出力
以下は1つのサンプル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の出力を調べてみましょう。
出力
上記では、読み取り用にjsonファイル(data1.json)を開き、ファイルハンドラーを取得して、json.loadに渡し、オブジェクトを取得します。オブジェクトの出力を出力しようとすると、jsonファイルと同じになります。オブジェクトのタイプは辞書ですが、Pythonオブジェクトとして出力されます。このピクルスを見たので、jsonへの書き込みは簡単です。上記では、jsonファイルをロードし、別のキーと値のペアを追加して、同じjsonファイルに書き戻します。data1.jsonを見ると、見た目が異なります。つまり、以前と同じ形式ではありません。
出力を同じように見せるために(人間が読める形式)、プログラムの最後の行にいくつかの引数を追加します。
json.dump(conf, fh, indent = 4, separators = (‘,’, ‘: ‘))
同様に、pickleのように、文字列をダンプで出力し、ロードでロードすることができます。以下はその例です、
YAML
YAMLは、すべてのプログラミング言語にとって最も人間に優しいデータシリアル化標準である可能性があります。
Pythonyamlモジュールはpyamlと呼ばれます
YAMLはJSONの代替手段です-
Human readable code − YAMLは最も人間が読める形式であるため、そのフロントページのコンテンツでさえYAMLで表示されます。
Compact code − YAMLでは、括弧ではなく構造を示すために空白のインデントを使用します。
Syntax for relational data −内部参照には、アンカー(&)とエイリアス(*)を使用します。
One of the area where it is used widely is for viewing/editing of data structures −たとえば、構成ファイル、デバッグ中のダンプ、およびドキュメントヘッダー。
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メソッド内にいて、関数.iexおよび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モジュールがロギングに参加できるため、アプリケーションログには、サードパーティモジュールからのメッセージと統合された独自のメッセージを含めることができます。それは多くの柔軟性と機能性を提供します。
ロギングの利点
Diagnostic logging −アプリケーションの操作に関連するイベントを記録します。
Audit logging −ビジネス分析のためにイベントを記録します。
メッセージは「重大度」&minuのレベルで書き込まれ、ログに記録されます
DEBUG (debug()) −開発用の診断メッセージ。
INFO (info()) −標準の「進行状況」メッセージ。
WARNING (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です。次に、debugステートメント、infoステートメント、warningステートメントの3つの異なるステートメントがあります。
logging1.pyの出力
INFO:root:This should be logged
WARNING:root:And this, too
infoステートメントはdebugステートメントの下にあるため、デバッグメッセージを表示できません。出力ターミナルでもデバッグステートメントを取得するには、変更する必要があるのは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
ベンチマーク
ベンチマークまたはプロファイリングは、基本的に、コードの実行速度とボトルネックがどこにあるかをテストすることです。これを行う主な理由は、最適化のためです。
timeit
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