Python3エンジニア認定基礎試験は、今アツいプログラミング言語Pythonの基礎力をはかるのに良い教材です。
今まで模擬テストの問題ベースに解説や調べて重要な内容を書いてきましたが、この記事は補講です。
公式テキストである、オライリーのPythonチュートリアル をながめながら見ていく中で必要な部分を抜き出していきます。
1回め、2回め、3回め、4回めはこちらです!
Pythonチュートリアルの内容
コメント
Pythonにおけるコメントは、 # (ハッシュ記号) だが、文字列リテラル(引用符で囲まれたものたち)の内部にはつけられない。
# 1つ目のコメント
coffee = 1 # 2つ目のコメント
# 3つ目のコメント
text = "# ここはコメントではない。"
数値
演算対象の型が混合していた場合、整数であれば浮動小数点数(float)に変換される。
これは直感的にわかりやすい。
>>> 3 * 3.75 / 100
7.5
>>> 7.0 / 2
3.5
文字列
シングルクォートとダブルクウォート
表示の引用符がダブルクウォートとなるのは、文字列自体にシングルクォートを含み、ダブルクウォートを含まない場合のみ。
文字列リテラルの結合
自動的に連結される。
>>> 'Py' 'thon'
Python
変数とリテラルの連結は、 + を使う
>>> prefix = 'Py'
>>> prefix + 'thon'
Python
死んだオウム(キーワード引数)
P.32 4.7.2 キーワード引数
オウムが死んでいる(state)の部分をキーワード引数を置き換えて変更(オーバーライド)できる。
voltageとvoomが入る部分はセリフ。
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print("-- This parrot wouldn't", action, end=' ')
print("if you put", voltage, "volts through it.")
print("-- Lovely plumage, the", type)
print("-- It's", state, "!")
# 出力1
parrot(1000)
# 出力1結果
-- This parrot wouldn't voom if you put 1000 volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's a stiff !
# 出力2
parrot(voltage=1000)
# 出力2結果
-- This parrot wouldn't voom if you put 1000 volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's a stiff !
# 出力3
parrot(voltage=1000000, action='VOOOOOOOOM')
# 出力3結果
-- This parrot wouldn't VOOOOOOOOM if you put 1000000 volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's a stiff !
# 出力4
parrot(action='VOOOOOOOOM', voltage=1000000)
# 出力4結果
-- This parrot wouldn't VOOOOOOOOM if you put 1000000 volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's a stiff !
# 出力5
parrot('a million', 'bereft of life', 'jump')
# 出力5結果
-- This parrot wouldn't jump if you put a million volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's bereft of life !
# 出力6
parrot('a thousand', state='publising up the daisies')
# 出力6結果
-- This parrot wouldn't voom if you put a thousand volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's publising up the daisies !
##################以下は無効##################
# 出力7(引数がない)
parrot()
# 出力7結果
Traceback (most recent call last):
File "func2.py", line 9, in <module>
parrot()
TypeError: parrot() missing 1 required positional argument: 'voltage'
# 出力8(キーワード引数のあとに、非キーワード引数)※順番が逆
parrot(voltage=5.0, 'dead')
# 出力8結果
File "func2.py", line 9
parrot(voltage=5.0, 'dead')
^
SyntaxError: positional argument follows keyword argument
# 出力9(同じ引数に値を2度与えた)
parrot(110, voltage=220)
# 出力9結果
Traceback (most recent call last):
File "func2.py", line 9, in <module>
parrot(110, voltage=220)
TypeError: parrot() got multiple values for argument 'voltage'
# 出力10(未知のキーワード引数)
parrot(actor='John Cleese')
# 出力10結果
Traceback (most recent call last):
File "func2.py", line 9, in <module>
parrot(actor='John Cleese')
TypeError: parrot() got an unexpected keyword argument 'actor'
仮引数 * と **
仮引き数の最後が **名前 の形になっていると、その引数はディクショナリを受け取る。ディクショナリには、仮引数に対応するキワードを除いた全てのキーワード引数が入っている
(= 仮引数にないキーワードが使える。)
また、 *名前 と組み合わせる事ができる。( *名前 は、 **名前 の前にある必要がある。)
この形式では、仮引数にない位置指定型引数をすべて含んだタプルが関数に渡る。
def cheeseshop(kind, *arguments, **keywords):
print("-- Do you have any", kind, "?")
print("-- I'm sorry, we're all out of", kind)
for arg in arguments:
print(arg)
print("-" * 40)
keys = sorted(keywords.keys())
for kw in keys:
print(kw, ":", keywords[kw])
cheeseshop("Limburger", "It's very runny, sir.",
"It's really very, VERY runny, sir.",
shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch")
# 出力
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch
keywordsディクショナリの中身を表示する際に、まずはkeys()メソッドの結果をソートし、キーワード引数のリストを作成している。これをしないと、引数の表示順序が不定になる。
shopkeeper=”Michael Palin”,
client=”John Cleese”,
sketch=”Cheese Shop Sketch”)
ここが、 **keywords にあたる、ディクショナリ型の引数の渡し方。
“It’s very runny, sir.”,
“It’s really very, VERY runny, sir.”,
ここが、*arguments にあたる、タプル型での引数の渡し方。
引数リストのアンパック
引数にしたいものが既にリストやタプルになっており、位置指定型引数の要求する関数のためにアンパックしないといけない場合、
例:range()関数が開始と停止で別々の引数を指定している。これらが個別に取得できないときには、
*演算子を使って関数をコールすることで、リストやタプルからアンパックした引数を渡すことができる。
>>> list(range(3,6))
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(args))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object cannot be interpreted as an integer
>>> list(range(*args))
[3, 4, 5]
**演算子で、ディクショナリ型をキーワード引数にして渡すことができる。
def parrot(voltage, state='a stiff', action='voom'):
print("-- This parrot wouldn't", action, end=' ')
print("if you put", voltage, "volts through it.", end=' ')
print("E's", state, "!")
d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
parrot(**d)
# 出力
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
lambda式
関数定義は通常はdefで定義するところ、キーワード lambdaを使うと小さな無名関数が書ける。
「lambda a, b: a+b」は、2つの引数の和を返す関数。
ラムダ関数は、関数オブジェクトが必要な場所全てに使用できる。
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
>>> f(2)
44
小さな関数を引数として渡すときにも利用できる。
>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
任意の関数を各要素に適用してその結果を元にソートできる。
l = ['Charle', 'Bob', 'Alice']
l_sorted = sorted(l)
print((lambda x: x[1])('Alice'))
# 出力
l
# 2文字目を取得するラムダ式を引数keyに指定すると、2文字目のアルファベット順にソートされる。
l = ['Charle', 'Bob', 'Alice']
print((lambda x: x[1])('Alice'))
#出力
l
l_sorted_second = sorted(l, key=lambda x: x[1])
print(l_sorted_second)
# 出力
['Charle', 'Alice', 'Bob']
比較演算子 条件(P. 54)
in / not in
シーケンスに値が存在するか(及び存在しないか)をチェックする。
is / is not
2つのオブジェクトを比較して完全に同一であるかを調べる(同一性が問題になるのは、リストのような可変オブジェクトのみ)。
優先度
比較演算子の優先順位は全て同等で、どれも全ての数値演算子より低い。
比較はブール演算子 and および or により組み合わせることができ、比較の結論は、notによる否定ができる。これらの優先順位は、比較演算子より低い。(この中では、notの順位が一番高く、orが最も低い。)
クラス
Pythonのクラスは、実行時に生成され、生成後にも改変可能。
スコープと名前空間
名前空間・・・名前とオブジェクトの対応付け(マッピング)のこと。ほとんどの名前空間は、Pythonディクショナリとして実装されている。
例:ビルトイン名、モジュールのグローバルな名前群、関数呼び出しにより生成されるローカルな名前群。
オブジェクトの属性群も名前空間を形成する。
※異なる名前空間同士の名前には一切の関わりがない。
属性・・・ドットに続くあらゆる名前のこと。
例:z.realの場合、realはzオブジェクトのz属性となる。(これには直接の対応付けがあり、同じ名前空間を共有している。)
スコープ・・・ある名前空間から直接アクセスできる、プログラムテキスト上の範囲のこと。
Pythonのスコープの種類↓
- ローカルスコープ
- ローカルスコープを囲むスコープ(enclosing scope)
- (モジュールレベルの)グローバルスコープ
- 組み込み名前空間を表すスコープ