Python

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動
Wikipedia
ウィキペディアPythonの記事があります。
ウィキバーシティ
ウィキバーシティPythonの学習教材があります。
Python

Pythonは高水準な汎用プログラミング言語です。 Pythonの設計思想は、コードの読みやすさを重視しています。 たとえばブロックは波括弧 { } ではなくインデントで構造化されているなど、その構造に対するアプローチは独特です。

また、Pythonは、オブジェクト指向・インタープリタ型・動的かたづけ・クロスプラットフォームなプログラミング言語です。 これらのアプローチは、プログラマーが小規模および大規模なプロジェクトで自己説明的で論理的なコードを書けるようにすることを目的としています。

目次[編集]

リファレンス[編集]

整理作業中[編集]

  • Python/整理中 (複素数、正規表現、HTTPクライアント、JSON、pass)

内包表記とジェネレータ式[編集]

Pythonには、シーケンスの内包表記とジェネレータ式があります。

内包表記とジェネレータ式
for label, expr in {"加算":"1 + 1",
    "リスト内包表記":"[2 ** x for x in range(5)]",
    "集合内包表記":"{2 ** x for x in range(5)}",
    "辞書内包表記":"{x: 2 ** x for x in range(5)}",
    "ジェネレータ式":"(2 ** x for x in range(5))",
    "タプルコンストラクターにジェネレータ式を適用":"tuple(2 ** x for x in range(5))",
    }.items() :
  print(f'{label}\n  {expr}\n{eval(expr)} : {type(eval(expr))}')
実行結果
加算:
  1 + 1
  ⇒ 2 : <class 'int'>
リスト内包表記:
  [2 ** x for x in range(5)]
  ⇒ [1, 2, 4, 8, 16] : <class 'list'>
集合内包表記:
  {2 ** x for x in range(5)}
  ⇒ {1, 2, 4, 8, 16} : <class 'set'>
辞書内包表記:
  {x: 2 ** x for x in range(5)}
  ⇒ {0: 1, 1: 2, 2: 4, 3: 8, 4: 16} : <class 'dict'>
ジェネレータ式:
  (2 ** x for x in range(5))
  ⇒ <generator object <genexpr> at 0x14ac1a9e56d0> : <class 'generator'>
タプルコンストラクターにジェネレータ式を適用:
  tuple(2 ** x for x in range(5))
  ⇒ (1, 2, 4, 8, 16) : <class 'tuple'>
Pythonの式を表す文字列(Ex. "1 + 1")を要素としたタプルをループ変数exprで回しています。
print(f'{label}:\n {expr}\n ⇒ {eval(expr)} : {type(eval(expr))}')は、
ラベル:
  式
  ⇒ 式の評価結果 : 式の評価結果の型
を表示します。
(2 ** x for x in range(5))は、タプル内包表記…ではなく、ジェネレータ式で未評価のシーケンス(generator)を返します(組込み関数のrange同様、この時点ではメモリーオブジェクトではありません)。
タプルのコンストラクターにジェネレータ式を渡すと、タプルが返ります(タプルはイミュータブルですがメモリーオブジェクトです)。

代入演算子[編集]

if文やwhile文の条件には式が要求されるので代入文 = は使えませんでした。 しかし、条件式の中で代入を行うのがふさわしいケースもあります。 このため Python 3.8で、条件式中でもつかえる代入演算子(Assignment Expressions) := (俗称:セイウチ演算子;Walrus operator)が導入されました[1]

代入演算子の使用例
a = "1234567" # 7文字
if (n := len(a)) > 5:
    print("文字が5文字より多いです" , n - 5, "文字オーバー")
    
print(f"あなたは{n} 文字を入力しました")
実行結果
文字が5文字より多いです 2 文字オーバー
あなたは7 文字を入力しました

代入演算子を使った条件式を含む文のブロックの外に出ても、そのまま代入した効果は残ります。

なお、f"あなたは{n} 文字を入力しました"はテンプレート・リテラルです。

エスケープシーケンス[編集]

たとえばprint()関数で、「こんにちは」と表示させたい場合なら

print("こんにちは")
と書きました。
もし「"」そのものを表示したい場合、いったい、どうすれば良いのでしょうか?
答えを先にいうと、
print("\"")
と記述します。
つまり「"」の直前に「\」(バックスラッシュ)を追加して「\"」と記述すると、文字列としての「"」になります。
このような方法をエスケープシーケンスといいます。

エスケープシーケンスの一覧[編集]

エスケープシーケンスの一覧
エスケープシーケンス 意味
\<改行> バックスラッシュと改行を無視
\\ バックスラッシュ自身 (\)
\' シングルクォーテーション (')
\" ダブルクオーテーション (")
\a ASCII ベ (BEL)
\b ASCII バックスペース (BS)
\f ASCII フォームフィード (FF)
\n ASCII ラインフィード (LF)
\r ASCII キャリッジリターン (CR)
\t ASCII 水平タブ (TAB)
\v ASCII 垂直タブ (VT)
\ooo 8進数キャラクタコードによる文字指定 ooo
\xhh 16進数キャラクタコードによる文字指定 hh

print関数[編集]

# 「ようこそ」 と出力
print("ようこそ")

#から行末まではコメントです。文字列の出力はprint()を使います。Python 2まではprintは文でしたが、Python 3では組込み関数printとなったため、かっこが必須となります。

文字列は" "で囲んでも' 'で囲んでも同じ意味であり、エスケープ文字の取り扱いに違いはありません。

備考[編集]

  • インデントについて

Pythonのブロックはスペース4つのインデントによって表されます(オフサイドルールといいます)。

  • pythonについて

pythonは、Googleなどの企業のみならず、MITの初年度のプログラミングの授業でも採用されています。英語圏ではRubyPerlよりも普及しています。

Pythonは1990年にグイド・ヴァンロッサムによって作られました。誰が書いても同じソースコードになるように(違う目的のコードは違う見た目になるように)設計されており、常に読みやすいプログラムを書くことができます。教育用プログラミング言語としても秀逸です。

書式化付き文字列化[編集]

C言語のsprintf()に相当する書式付き文字列化は、Pythonでは文字列の % 演算子を使います。 また、書式化文字列に % によるフィールドが複数ある場合は、下のようにタプルを使います。

>>> print("%d.%d.%d" % (2, 6, 4))
2.6.4

pip[編集]

pipはPythonのパッケージインストーラーです[2]。Python Package Index[3] などのインデックスからパッケージをインストールするのに使用します。

pipがインストールされているかは、(インターラクティブ・モードではなく)コマンドラインから確認します。

FreeBSD
% uname
FreeBSD
% pip -V
pip 20.3.4 from /usr/local/lib/python3.10/site-packages/pip (python 3.10)
Windows 10
PS C:\Users\user1> pip.exe -V
pip 21.2.4 from C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2544.0_x64__qbz5n2kfra8p0\lib\site-packages\pip (python 3.9)
GNU/Linux
~ $ uname
Linux
~ $ pip -V
pip 21.2.4 from /data/data/com.termux/files/usr/lib/python3.10/site-packages/pip (python 3.10)


YAML[編集]

YAMLは、構造化データやオブジェクトを文字列にシリアライズするためのデータ形式の一種です。 Pythonは、初期状態ではYAMLを利用できませんが、pyYaml [4]をインストールすることで、pythonでYAMLを処理できるようになります。

pipがインストール済みならば、

コマンドライン
% sudo pip install pyyaml

で pyYaml をインストールできます。 YAMLとPythonは別個の出自なのですが、YAMLはデータ構造をインデントで表し[5]、Pythonはプログラム構造をインデントをあらわすので似通った外観になります。

YAMLファイルの読出し[編集]

test.yaml
名前: 
  : 山田
  : 太郎
国籍: 日本
性別: 
部活: 野球部
test-yaml.py
import yaml

with open('/workspace/test.yaml') as f:
    obj = yaml.safe_load(f)
print(f"""\
{obj=}
{obj["国籍"]=}
{obj["名前"]["姓"]=}
""")
実行結果
obj={'名前': {'姓': '山田', '名': '太郎'}, '国籍': '日本', '性別': '男', '部活': '野球部'}
obj["国籍"]='日本'
obj["名前"]["姓"]='山田'
import で yaml をインポートする必要があります。
pythonでYAMLのセミコロンのデータを読取った場合の辞書型のオブジェクトを返します

かつてYAMLの読取りには、yaml.load()が使われていましたが、セキュリティ上の懸念から deprecated となり、yaml.load() を使うと

Main.py:4: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.

と警告されます。yaml.safe_load() を使いましょう。

オブジェクトのYAMLへの変換[編集]

コード例
import yaml
obj = {
    "a": [2,3,5,7],
    "b": 3.14,
    "c": "test test",
    }

s = yaml.dump(obj)
print("*** Block style ***")
print(s);
print("*** Load ***")
print(yaml.safe_load(s))
s = yaml.dump(obj, default_flow_style=True)
print("*** Flow style ***")
print(s);
実行結果
*** Block style ***
a:
- 2
- 3
- 5
- 7
b: 3.14
c: test test

*** Load ***
{'a': [2, 3, 5, 7], 'b': 3.14, 'c': 'test test'}
*** Flow style ***
{a: [2, 3, 5, 7], b: 3.14, c: test test}

YAMLファイルの書込み[編集]

コード例
import yaml

obj = {
    "a": [2,3,5,7],
    "b": 3.14,
    "c": "test test",
    }
with open('/workspace/test.yaml', "w") as f:
    yaml.dump(obj, f)

with open('/workspace/test.yaml') as f:
    for s in f: 
        print(s, end='')
print("-"*40)
with open('/workspace/test.yaml') as f:
    print(yaml.safe_load(f))
実行結果
a:
- 2
- 3
- 5
- 7
b: 3.14
c: test test
----------------------------------------
{'a': [2, 3, 5, 7], 'b': 3.14, 'c': 'test test'}

pickle と marshal[編集]

pickleモジュールは、Pythonのオブジェクト構造をシリアル化およびデシリアル化するためのバイナリプロトコルを実装しています[6]。 marshalモジュールも、Pythonのオブジェクト構造をシリアル化およびデシリアル化するためのバイナリプロトコルの実装ですが、将来に渡ってフォーマットを変えないことは保証されていないので、その用途にはpickleモジュールあるいはshelveモジュールを使ってください[7]。 marshalモジュールは、主に.pycファイルのPythonモジュールの "擬似コンパイル "コードの読み書きをサポートするために存在します。

コード例
import pickle

obj = [1,3,5,7]
obj.append(obj)
print(f'{obj=}')

pkl = pickle.dumps(obj)
print(f'{pkl=}')
print(f'{pickle.loads(pkl)=}')

import marshal

msl = marshal.dumps(obj)
print(f'{msl=}')
print(f'{marshal.loads(msl)=}')
実行結果
obj=[1, 3, 5, 7, [...]]
pkl=b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01K\x03K\x05K\x07h\x00e.'
pickle.loads(pkl)=[1, 3, 5, 7, [...]]
msl=b'\xdb\x05\x00\x00\x00\xe9\x01\x00\x00\x00\xe9\x03\x00\x00\x00\xe9\x05\x00\x00\x00\xe9\x07\x00\x00\x00r\x00\x00\x00\x00'
marshal.loads(msl)=[1, 3, 5, 7, [...]]

shelve[編集]

shelveモジュールは、永続的な辞書の実装です[8]

コード例
import shelve

filename = "/workspace/temp.shelve"
with shelve.open(filename) as sh:
    sh['x'] = 1
    sh['y'] = "abc"
    sh['z'] = [0, 1, 2]
    print(f'{sh["z"]=}')

with shelve.open(filename) as sh:
    print(f'{ {k:v for k,v in sh.items()}=}')
実行結果
sh["z"]=[0, 1, 2]
 {k:v for k,v in sh.items()}={'z': [0, 1, 2], 'x': 1, 'y': 'abc'}

脚註[編集]

  1. ^ PEP 572 -- Assignment Expressions” (2018年2月28日). 2021年11月12日閲覧。
  2. ^ pip documentation v21.3.1” (2021/12/20 accessdate=2021/12/20).テンプレート:Cite web/error
  3. ^ The Python Package Index (PyPI) is a repository of software for the Python programming language.” (2021/12/20 accessdate=2021/12/20).テンプレート:Cite web/error
  4. ^ https://github.com/yaml/pyyaml
  5. ^ インデントでデータ構造を表すスタイルをブロックスタイルと呼びます。YAMLには他にフロースタイルと言う形式があり、これはYAML1.2からはJSONそのものです。YAML Ain’t Markup Language (YAML™) version 1.2
  6. ^ 3.10.0 Documentation » The Python Standard Library » Data Persistence » pickle — Python object serialization” (2021年12月2日). 2021年12月2日閲覧。
  7. ^ 3.10.0 Documentation » The Python Standard Library » Data Persistence » marshal — Internal Python object serialization” (2021年12月2日). 2021年12月2日閲覧。
  8. ^ 3.10.0 Documentation » The Python Standard Library » Data Persistence » shelve — Python object persistence” (2021年12月2日). 2021年12月2日閲覧。
このページ「Python」は、まだ書きかけです。加筆・訂正など、協力いただける皆様の編集を心からお待ちしております。また、ご意見などがありましたら、お気軽にトークページへどうぞ。