←PC版は別ページ

≪いっしょにPython≫ プログラマーの実験ノート

 このページは,プログラム言語Pythonをこれから学ぼうと考えている筆者の備忘録です.
 そこそこ調べて書いていますが,仕様を精密に調べたものではありません.どちらかと言えば,実装されたPython 3を使ってみてどうなったかということを中心に書いたものです.いわば,実験ノートの記録です.(最終更新年月日:2019.4.17 / by Python 3.7.3)
Pythonの練習には,
(1) IDLEというメニューから入って,>>>というプロンプトが表示される状態で使う場合
• 画面の上端がPython 3.7.x Shellとなっていて,2行目がFile, Edit, Shell, Debug, ...となっている
• 1行入力するたびに,エラーを確かめながら処理を進める,対話型インタプリタの形になっている
(2) IDLEというメニューから入って,左上端のFileをクリック→New Fileと進む場合
• 画面の上端がファイル名(初めはUntitled)となっていて,2行目がFile, Edit, format, Run, ...となっている
(3) Python 3.7.x という真っ黒なコマンドプロンプトの画面(ターミナルウィンドウ)から入るもの
の3通りが使えるが,以下は(2)のNew Fileから,テキストエディタを使って,プログラムを書く場合を考える.

1. Pythonで使える変数名

(1) 半角(1バイト文字)の「大文字・小文字の英字」「数字」「アンダースコア」が使える

@) Pythonで変数名に使える文字は,「大文字・小文字の英字(A〜Z, a〜z)」「数字(0〜9)」「アンダースコア(_)」の3種類を組み合わせた文字に限る.
【使える例】
aA ←ただし,あまりに単純な1文字は,他で使われやすいので避けた方がよい
a1A2
dog_catdogCatDogCat
【使えない例】
a.b → ドット(.)は使えない
times new → スペースを含む文字は,1つの名前と認識されない
abc@xyz → アットマーク(@)は使えない
osaka+kita → 演算記号(+)は使えない
tiyoda-tokyo → 演算記号(-)は使えない
kyoto*minami → 演算記号(*)は使えない
a/z → 演算記号(/)は使えない
A) ただし,数字を先頭の文字として使うことはできない.
【使えない例】
1a → 先頭が数字の名前は使えない
123 →先頭が数字の名前は使えない
B) 先頭がアンダースコア(_)となっている名前は,Pythonのシステムにおいて特別な使われ方をしているので,特に必要な場合を除けば,先頭がアンダースコアとなっている名前も避けた方がよい.
【使えない例】
_a → 先頭がアンダースコア(_)1つの名前は,一応使えるが,お勧めではない
__a__ → 先頭がアンダースコア(_)2つの名前は,一応使えるが,お勧めではない<
C) 英字は大文字(A〜Z)と小文字(a〜z)を区別するので,これらが異なる名前は別の変数になる.
【例】
a1 = 3
A1 = 5
のとき,print(a1, A1)によって,3も5も表示される
D) 約40個の単語は,Pythonにおいて特別な使われ方をする予約語となっており,この予約語に一致する単語は変数名として使えない.
【使えない例】
andasifisin
Truefalseforwhilebreak
⇒ それでは,予約語と衝突しないように,予約語を覚えなければならないか?というと,そうでもなく,もっと簡単な覚え方がある.これは,筆者の覚え方であるが,「予約語は英語の単語になっている」から「単語でないもの」,たとえば
英字で始まり,途中または末尾に数字を使っている綴り(abc1, man2, str3など)
2つ以上の単語を組み合わせる
• キャメル記法:myFirstName[英小文字で書き始め,2つ目以後の単語の先頭を大文字で書く.ラクダ(キャメル)のこぶに似ているのでキャメル記法と呼ばれる]
• アンダーバー記法:my_first_name[2つ以上の単語をアンダーバーでつないでいく]
• パスカル記法:MyFirstNameなど[英大文字で書き始め,2つ目以後の単語の先頭を大文字で書く.パスカルという言語で使われた書き方])
はすべて使える.
【変数名の付け方】お勧めの方法 ≪要約≫
• 英小文字で書き始めて,数字を末尾に付けると決める.(2つ以上必要になれば2,3,4..としていく)
str1, num1など
•特別な使われ方の変数だけ英大文字で書き始めて,以下同様にする.
Str1, Num1など
• キャメル記法, アンダーバー記法, パスカル記法のうちで自分のスタイルを決めておく.
myName, my_name, MyName など
【日本語の変数名,関数名】
※Python 3では,実際には,日本語の変数名も使えます.例えば,次のプラグラムは正常に動きます.
IDLE → New File → Save as ..
変数1 = 12
print(変数1)
 関数名についても,全く同様に日本語を使うことができます.
IDLE → New File → Save as ..
def 関数あ():
    print('あ')
関数あ()
他の多くのプログラミング言語では,このような取り扱いはなされていないので,かなり違和感があります.
IDLE → New File → Save as ..
朝のあいさつ='おはよう'
昼のあいさつ='こんにちは'
print(朝のあいさつ, 昼のあいさつ)
 また,小学生向けのLOGOと違って,全角(2バイト)文字で入力した等号(=)や括弧が本来の半角(1バイト)文字に等しいと見なされる訳でもないので,全角文字の=や( )を使って書くとエラーになります.
※筆者の考えでは,日本語の変数名,関数名を使うことは長い目で見てメリットよりはデメリットの方が多いように思う…他でも使えると思ってしまう点,国際化に対応できない点,コマンドと文字列の区別があいまいになる点.

2. 関数の定義と呼び出し

(1) 引数なしの関数

【関数定義の書き方】
def 関数名():
処理
【関数呼び出しの書き方】
関数名()
• 関数名の付け方の規則は,変数名の付け方と同じです.
【例 2.1.1】
IDLE → New File → 保存してから Run
def func1():
    print('おはよう')
func1()
defで始めると関数の定義になる
関数本体は,ここでは'おはよう'の表示のみ
defなしで直接に関数名()と書いたものは,関数呼び出し(=実行)

→ おはよう
• ただし,変数名と関数名に同一の名前を付けてしまった場合は,後から書いた方が上書きするので,先に書いた方が無効になります.変数相互,関数相互の場合でも,この事情は同じです.(後出しのジャンケンが勝ちます)
【例 2.1.2】
IDLE → New File → 保存してから Run
def func1():
    print('おはよう')
func1 = 5
def func1():
    print('こんにちは')
func1()
→ こんにちは
• 1つのpyファイルを読み込む場合,ファイルの前から順に読みだして処理するので,関数呼び出しが関数の定義よりも前に書いてあればエラーになります.(前方参照はダメです)
【例 2.1.3】
IDLE → New File → 保存してから Run
func1()
x = 5
def func1():
    print('おはよう')
→ エラー
• ただし,ファイル読み込み後,何らかのタイミングで関数呼び出しが行われるときは,物理的に前に書かれていなくても,関数呼び出し(=実行)の時点で関数定義が読み込まれていれば,問題ありません.
【例 2.1.4】
IDLE → New File → 保存してから Run
def func0():
    str1 = input('1か2を入力してください')
    if str1 == '1':
        func1()
    else:
        func2()
def func1():
    print('おはよう')
def func2():
    print('こんばんは')
func0()
→ 1なら'おはよう',2なら'こんばんは'(引用符はない)
(関数定義があっても,その個所では実行されるわけではない.関数func0()が実行されるときには,func1()もfunc2()も読み込まれている)
• 引数なしで関数が定義されているときに,関数の呼び出し(=実行)において引数を指定するとエラーになる.
• 逆に,n個の引数を持つ関数として定義されているときに,関数の呼び出し(=実行)においてそれよりも少ない個数の引数を与えた場合もエラーになる.(後で登場する)
【例 2.1.5】
IDLE → New File → 保存してから Run
def func1():    
    print('こんにちは')
func1('a')    
→ エラー(引数なしで定義されている関数を,引数を付けて呼び出し[実行]している)

(2) 位置引数のある関数

• 関数に引き渡す値を引数という.引数のうちで,第1引数,第2引数,第3引数,...のように,何番目の引数を何に使うかが決めてあるものを,位置引数という.
【関数定義の書き方】
def 関数名(第1引数, 第2引数, 第3引数, ..):
処理
【関数呼び出しの書き方】
関数名(第1引数, 第2引数, 第3引数, ..)
【例 2.2.1】
IDLE → New File → 保存してから Run
def f1(width, height):    
    print(width * height)    
f1(4, 5)    
f1('すみません', 3)    

20
すみません すみません すみません
(関数の定義式に示されている引数を仮引数,関数呼び出し(=実行)で使われる引数を実引数と呼ぶことが多い.上の関数では,横の長さwidthと縦の長さheightを引数として渡すと面積が求められるという意味を込めて,仮引数の名をwidth, heightとしているが,実際には関数本体において同じ綴りの変数が使われさえすればよく,横の長さ,縦の長さを表していなくても関数としては指定された働きをする.2つ目の例は,文字列 * 回数が文字列の繰り返しを表すことを利用したものです)

(3) 位置引数と戻り値のある関数

• 関数の戻り値はreturn文で示される.戻り値があれば,関数の外でその値を利用することができる.
• 制御の流れに関しては,return文に出あうと(ループの中でbreak文に出あったときとよく似て)以後の処理を行わずに打ち切り,関数の外に出るという働きがある.
【関数定義の書き方】
def 関数名(第1引数, 第2引数, 第3引数, ..):
処理
return 式
【関数呼び出しの書き方】
変数名 = 関数名(第1引数, 第2引数, 第3引数, ..)
【例 2.3.1】
IDLE → New File → 保存してから Run
def seiWari(a1, b1):    
    if isinstance(a1, int) == False:    
        return False    
    if isinstance(b1, int) == False:    
        return False    
    if b1 == 0:    
        return False    
    r1 = a1 % b1    
    return r1    
amari = seiWari(31, 7)    
print(amari)    
関数isinstance(a1, int)は引数a1がint型であればTrueを返す

戻り値は関数の外部の変数amariに代入される


→ 3

(4) 戻り値が2個以上ある関数

• return文でタプルを返せば,2つ以上の値を戻り値として返せる.
• return (x1, y1, z1, ...)もしくは括弧を省略して,return x1, y1, z1, ...の形で書けば,タプルの型で返せる.
• タプルは,a1, b1, c1, ... = タプルの変数 の形で一度に代入できる.
【例 2.4.1】
整数割り算をして,商と余りを返す
IDLE → New File → 保存してから Run
def seiWari(a1, b1):
    if isinstance(a1, int) == False:
        return False
    if isinstance(b1, int) == False:
        return False
    if b1 == 0:
        return False
    r1 = a1 % b1
    q1 = (a1 - r1)/b1
    return (b1, r1)
syo1, amari1 = seiWari(31, 7)
print(syo1, amari1)
→ 7 3

(5) キーワード引数を使った関数呼び出し

• 位置引数を使って関数を呼び出すには,第1引数,第2引数,...それぞれの働きを知っていなければならない.例えば,第1引数と第2引数を入れ換えて関数を呼び出すと結果が変わるのが普通である.
• これに対して,関数定義において仮引数として使われている文字を使って引数を指定すると,引数の順序は自由に変えられる.
• 関数の定義を見て,「引数の順序を覚える」「仮引数の文字を覚える」のどちらでもよいことになる.
【関数定義】
def 関数名(arg1, arg2, arg3, ..):
処理
return 式
【キーワード引数の使い方】
関数名(arg1=x, arg2=y, arg3=z, ..)
【例 2.5.1】
IDLE → New File → 保存してから Run
#グローバル変数を使った,好きなものリスト
sport1 = ['サッカー','卓球','バレー']
fruit1 = ['りんご','みかん','かき']
nigiri1 = ['マグロ','サーモン','うに','いか']
#関数の定義
def like1(s_num, f_num, n_num):
    return sport1[s_num], fruit1[f_num], 
nigiri1[n_num]
#位置引数による関数呼び出し
child1, child2, child3 = like1(2,0,1)
print(child1, child2, child3)
#キーワード引数による関数呼び出し
father1, father2, father3 
= like1(n_num=3, s_num=0, f_num=1)
print(father1, father2, father3)

バレー りんご サーモン
サッカー みかん いか
※関数の中から,グローバル変数を読み出すことはできる.(ただし,関数の中からグローバル変数を書き換えるには,所定のglobal宣言という手続きが必要.)
※キーワード引数による関数呼び出しでは,キーワードが一致していれば,順序は問われない.

(6) デフォルト引数を使った関数定義

• 関数呼び出しのときに引数が省略された場合に,デフォルト(既定値)を使うようにする
【関数定義】
def 関数名(arg1=val1, arg2=val2, arg3=val3, ..):
処理
return 式
【例 2.6.1】
与えられた数のn乗を計算する関数を作る.指数(index1)が省略されたら2乗を求める
def my_pow(num,index1=2):
  return num ** index1
print(my_pow(3))
→ 9 (第2引数が省略されているから2乗の計算になる)
print(my_pow(2,3))
→ 8 (第2引数が書かれているからそれを使う)
print(my_pow())
→ エラー (第1引数はデフォルト値が設定されていないから省略できない)

(7) 可変長の引数をとる関数定義

@) 引数の個数が何個であっても対応できる関数を作るには,引数の前にアスタリスク(*)を付ける.
A) このアスタリスクはC言語などで使われるポインタとは異なり,アドレスという意味ではない.Pythonでの可変長引数の定義と読む.
B) Pythonでは可変長引数としてargsという文字がよく使われるが,他の文字でもよい.
C) 位置引数と可変長引数を併用するときは,可変長引数を後に書く.
D) 関数呼び出しにおいて,可変長引数はタプルとして渡され,可変長引数が省略されれば,空のタプルが渡される.
【関数定義】
def 関数名(x1, y1, *args):
処理
return 式
【例 2.7.1】
#数字を何個書かれても,それらの積を返す
def product_n(*args): # 引数を*argsと書くとき
  pp = 1
  for xx in args: # argsは実引数のタプルになる
    pp *= xx
  print(pp)
product_n(2,3,4,5)
product_n()

120 (2 * 3 * 4 * 5だから120になる)
1  (引数が省略された場合,forループが実行されないから,初期値のpp=1が表示される)

【例 2.7.2】
長い文章中に使われているアルファベットの個数を調べる
str1 = 'A certain man had a donkey, which had carried the corn-sacks to the mill indefatigably for many a long year; but his strength was going, and he was growing more and more unfit for work. Then his master began to consider how he might best save his keep; but the donkey, seeing that no good wind was blowing, ran away and set out on the road to Bremen. "There," he thought, "I can surely be town-musician." When he had walked some distance, he found a hound lying on the road, gasping like one who had run till he was tired. "What are you gasping so for, you big fellow?" asked the donkey.' # (グリム童話集「ブレーメンの音楽隊」の第1段落)
def count_char(*ch_set): # 引数を*ch_setと書くとき
  str2 = str1.lower() #大文字も小文字も数えるように,小文字に直す
  for ch in ch_set: # ch_setは実引数のタプルになる
    print(str2.count(ch)) # 文字列.count(ch)で文字列中の文字chの個数になる
count_char('a','b','c','d','e')

41
9
9
23
49

【例 2.7.3】
入力された人名を50音順に並べて表示する
def meibo1(*names): # 人数を定めずに*namesで受ける
  list1 = sorted(names) # nameはタプル型,list1はそれをソートしてリスト型にしたもの
  print(names)
  print(list1)
meibo1('みなもと','とよとみ','たいら','とくがわ')

('みなもと', 'とよとみ', 'たいら', 'とくがわ') # nameはタプル型
['たいら', 'とくがわ', 'とよとみ', 'みなもと'] # list1はそれをソートしたリスト型


3. グローバル変数とローカル変数

@) 関数の外で定義された変数を関数の中で使い,関数の中で求めた値を関数の外で利用するには,引数として入れて戻り値として出すという安全な方法がある.以下の方法は,その方法ではなくて,関数の内外で変数を直接に読み書きせざるを得ない場合の覚書である.
A) Pythonの変数は,C言語などとは異なり,Javascriptと似て,初めに型宣言をしていなくても,プログラムの途中で定義できる.
B) 各々の変数は,それが定義されている場所に応じて有効な範囲(スコープ)が決まる.
C) 関数の外で定義された変数はグローバル変数(global)で,関数の中からでも,関数の外からでも参照(読み出すこと)できる.
D) 関数の中で定義された変数はローカル変数(local)で,関数の外からは参照(読み出すこと)できない.
E) 関数の名からグローバル変数を書き換えるには,関数の中でその変数をグローバル変数として使うことを示すために,global宣言を行う.
 1つ上の階層の変数を参照して変更するには,nonlocal宣言を行う.
F) 同じ名前の変数を,グローバル変数とローカル変数の両方に使うのは,なるべく避ける方がよい.
G) C言語やJavascriptとは異なり,Pythonではブロックごとにスコープを分けることはないので,for文やif文の内外は全く同じスコープと解釈される.要するに,同じ関数の中にあるかどうかだけが重要で,インデントによるブロックの階層は区別されない.
【例 3.1.1】
与えられた2数の商と余りを求める
a1, b1はグローバル変数
a1 = 30
b1 = 7
関数定義には,a1, b1は登場しない
def syo_amari(x1, y1):
  r1 = x1 % y1
  q1 = (x1 - r1) // y1
  return q1,r1
@) 関数呼び出しの引数にa1, b1を使い,戻り値をグローバル変数に代入する
A) 必要な変数syo1, amari1は,プログラムの途中で定義できる.
syo1, amari1 = syo_amari(a1, b1)
print(syo1, amari1)
→ 4 2
【例 3.1.2】
x1はグローバル変数,x2はローカル変数
x1 = 3
def func1():
  print(x1)
  x2 = 5
func1() # C) 関数の中からx1は読める
print(x2) # D) 関数の外からx2は読めない
→ 3
エラー
【例 3.1.3】
x1 = 3 # x1はグローバル変数
def func1():
  x1 = 5 # x1に代入しているから,このx1はローカル変数
  print(x1)
func1()
print(x1)

5 # func1()が表示したのはローカル変数のx1の値
3 # func1()実行後もグローバル変数x1の値は変わらない
【例 3.1.4】
x1 = 3 # x1はグローバル変数
def func1():
  global x1 #E) 関数の中でも,グローバル宣言をすればグローバル変数を変更できる
  x1 = 5
  print(x1)
func1()
print(x1)

5 # func1()が表示したのはグローバル変数のx1の値
5 # func1()実行後,グローバル変数x1の値は変わっている
【例 3.1.5】
x1 = 1
def func1():
  for n1 in range(2, 3):
    for n2 in range(3, 4):
      n3 = 4
      print(x1,n1,n2,n3)
    print(x1,n1,n2,n3)
  print(x1,n1,n2,n3)
func1()

1 2 3 4 # 深い階層から浅い階層が見えるのは当然
1 2 3 4
1 2 3 4 # 浅い階層からでも深い階層が全く同じように見える
関数内で別の関数が定義されている場合は,スコープは3段階に分かれる
【例 3.1.6】
x1 = 0 # グローバル変数
def func1():
  x1 = 1 # 関数func1()のローカル変数
  def func2():
    x1 = 2 # 関数func1()の内部の関数func2()のローカル変数
    print(x1)
  func2()
  print(x1)
func1()
print(x1)

2 # 最も深い階層のローカル変数
1 # 関数func1()の内部のローカル変数
0 # グローバル変数
global宣言は1つ上の階層ではなく,最上位のglobalと解される
【例 3.1.7】
x1 = 0 # グローバル変数
def func1():
  x1 = 1 # 関数func1()のローカル変数
  def func2():
    global x1 #E) global宣言
    x1 = 2 # グローバル変数
    print(x1)
  func2()
  print(x1)
func1()
print(x1)

2 # 最も深い階層のローカル変数
1 # 関数func1()の内部のローカル変数
2 # グローバル変数
1つ上の階層は,nonlocal宣言で参照・変更できる
【例 3.1.8】
x1 = 0 # グローバル変数
def func1():
  x1 = 1 # 関数func1()のローカル変数
  def func2():
    nonelocal x1 #E) nonlocal宣言
    x1 = 2 # 関数func1()のローカル変数
    print(x1)
  func2()
  print(x1)
func1()
print(x1)

2 # 最も深い階層のローカル変数
2 # 関数func1()の内部のローカル変数
0 # グローバル変数

【補足:名前空間,変数のスコープ(scope)
 ある変数の有効範囲(寿命)をその変数のスコープ(scope)という.上記3.を一部再掲すると
B) 各々の変数は,それが定義されている場所に応じて有効な範囲(スコープ)が決まる.
C) 関数の外で定義された変数はグローバル変数(global)で,関数の中からでも,関数の外からでも参照(読み出すこと)できる.
D) 関数の中で定義された変数はローカル変数(local)で,関数の外からは参照(読み出すこと)できない.
E) 関数の名からグローバル変数を書き換えるには,関数の中でその変数をグローバル変数として使うことを示すために,global宣言を行う.
 1つ上の階層の変数を参照して変更するには,nonlocal宣言を行う.(Python 3)
F) 同じ名前の変数を,グローバル変数とローカル変数の両方に使うのは,なるべく避ける方がよい.
D) により,関数の中で定義されたローカル変数のスコープは,その関数の中だけで,関数の外からその変数を直接読むことはできない.
C) により,関数の外で(プログラムのメインの部分で)定義された変数は,グローバル変数と呼ばれ,そのモジュールの中のどこからでも読むことができる.
 ただし,E) により,グローバル変数を関数の中から書き換えるのは(変数に値を代入するのは)できない.関数の中において,無断で変数に値を代入している場合は,仮にグーバル変数と同名であっても,その変数はローカル変数を定義して代入したものとして扱われ,グローバル変数の方は変化しない.
E) により,関数の中で,グローバル変数を書き換える(グローバル変数に値を代入する)必要がある場合には,その関数の中で,その変数をglobal宣言しなければならない.
global 変数1
 Pythonでは,原則として他のステートメントを実行してからでも変数宣言を行うことができるが,1つの関数の中で,無断で変数に値を代入した場合,その変数はローカル変数になるので,後から同一名の変数をglobal宣言して使用するとエラーになる.
 global宣言した変数は,プリグラムの一番外側にあるメインの部分で定義されているものと見なされるのに対して,nonlocal宣言した場合(Python 3)は,関数がネスト(入れ子)になっている場合の1つ外側を表し,global変数を表すとは限らない.(例えば,関数の中で関数の定義が2段階ネストしている場合)
nonlocal 変数1
 プログラムのメインの部分とか,1つの関数の中のように場所を決めると,その場所から参照できる変数や関数の名前が決まる.このように,場所ごとに定まる変数や関数の全体は「名前空間」と呼ばれる.ある場所でのローカルな名前空間は,組み込み関数locals()によって変数名とその値が辞書として示され,関数はそのメモリアドレスが示される.グローバルな名前空間は,globals()によって示されるが,こちらの方はシステムが使っている__name__など多くのものが出てくる.
このプログラムで,#1の場所で示されるのは,{'x2': 7}という要素が1つの辞書になる.
#2の場所で示さるのは,実際にはglobals()と同一になり,{'x1': 5, 'func1': そのアドレス, ...}を含む多くの変数(プロパティ)になる.
※Pythonでは,標準ライブラリやユーザ作成モジュールをインポートして使うことが多い.その場合に,
from モジュール名 import *
と記述すると,そのモジュールのすべてのオブジェクト,すべてのグローバル変数がインポートされる.この方法は一見すると便利であるが,作業中のファイルで使っているオブジェクトやグローバル変数と同一の名前のものがあると上書きされるリスクを伴う.プログラマによっては,このような状況を「名前空間が汚れる」などと嫌う.
○== メニューに戻る ==