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}
    {expr}
{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('"')
print("\"")
print("\42")
print("\x22")
  1. クオート文字を ' に変えました。素朴ですがパワフルな方法です。
    しかし、この方法では " と ' は1つの文字列の中で共存できません。
  2. " の前に \ を前置すると文字列を閉じる " を打消すことができます。
    \ は、¥(円記号)の半角で表示されるかもしれませんが、文字コードと機能は同じです。
  3. \ に続けて " の文字コードを8進数で表記します。
    10進数ではないので注意してください。
  4. \ に続けて x それに続けて文字コードを16進数で表記します。

2. から 4. の様に、 \ を前置して文字列中に所望に文字を書く方法をエスケープシーケンス( escape sequence )といい、エスケープシーケンスに前置する文字 ' をエスケープ文字( escape character )といいます。

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

エスケープシーケンスの一覧
エスケープシーケンス 意味
\<改行> バックスラッシュと改行を無視
\\ バックスラッシュ自身 (\)
\' シングルクォーテーション (')
\" ダブルクオーテーション (")
\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
\uxxxx 16ビットの16進数値xxxxを持つUnicode文字
\Uxxxxxxxx 32ビットの16進数値xxxxxxxxを持つUnicode文字

print関数[編集]

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

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

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

備考[編集]

  • インデントについて

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

  • pythonについて

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

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

文字列の書式化[編集]

Pythonには、いくつかの異なる文字列の書式化の方法があります。

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

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

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

文字列の format メソッド[編集]

文字列の format メソッドを使う方法[2]

>>> print("{} {} {}".format(2, 6, 4))
2.6.4

f文字列[編集]

PEP 498で新しく f文字列 が追加されました[3]

>>> print(f"{4} {9} {8}")
4 9 8
文字列の書式化
print("%d %d %d" % (0!=0, 0==0, 999))
print("{} {} {}".format(0!=0, 0==0, 999))
print(f"{0!=0} {0==0} {999}")
print(f"{abs(-123)} {2**10} {999}")
実行結果
0 1 999
False True 999
False True 999 
123 1024 999

pip[編集]

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

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

FreeBSD
% uname
FreeBSD
% pip -V
pip 22.1 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 -a
Linux localhost 4.14.275-19064-g577a877aa35d #1 SMP PREEMPT Wed May 25 19:32:47 PDT 2022 x86_64 Intel(R) Celeron(R) N4020 CPU @ 1.10GHz GenuineIntel GNU/Linux
$ pip -V
pip 21.3.1 from /usr/local/lib/python3.10/site-packages/pip (python 3.10)


YAML[編集]

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

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

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

で pyYaml をインストールできます。 YAMLとPythonは別個の出自なのですが、YAMLはデータ構造をインデントで表し[7]、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のオブジェクト構造をシリアル化およびデシリアル化するためのバイナリプロトコルを実装しています[8]。 marshalモジュールも、Pythonのオブジェクト構造をシリアル化およびデシリアル化するためのバイナリプロトコルの実装ですが、将来に渡ってフォーマットを変えないことは保証されていないので、その用途にはpickleモジュールあるいはshelveモジュールを使ってください[9]。 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モジュールは、永続的な辞書の実装です[10]

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