Python入門 - 継承と包含 考え方編
継承とは?
あるクラスの特性(つまり、データや機能)を別のクラスに引き継がせることを「継承(英語でインヘリタンス)」と言います。
例えば、「動物」を考えてみましょう。一口に「動物」といっても、その中には「人」もあれば、「魚」もあります。他にも「犬」や「鳥」もあるでしょう。この時、「人」や「魚」は別のクラスだと言えますが、どちらも「動物」の一種です。例えば「動物」は「ものを食べる」という機能を持っています。「人」も「魚」も「ものを食べる」生き物ですが、これは「人」も「魚」も、どちらも「動物」だからですね。
この「BはAである(B is a A)」という関係を「is-a」関係と言います。
「is-a」関係をプログラム上で表現したものが、継承です。つまり、「動物」クラスを継承して「人」クラスを作成するということです。この時、軽傷元である「動物」クラスを「親クラス(スーパークラス)」といい、軽傷先である「人」クラスを「子クラス(サブクラス)」と言います。
継承は便利な機能で、オブジェクト指向プログラミングの大事な要素ですが、上手に使わないと、とてもわかりにくいプログラムになってしまいます。継承は、クラスとクラスの間に強い「依存関係」を作るからです。継承は明確な「is-a」関係がある時に、継承すべきかどうか考えるようにしましょう。
また、次に呼べる「包含」を利用すべきではないかも一緒に考えましょう。
包含とは?
先ほどの「動物」の例えを使ってもう少し考えてみましょう。他にも「人」や「魚」、「鳥」に共通する要素はないでしょうか?割とたくさん思いつくのではないでしょうか?例えば、「骨」とか「脳」とか「筋肉」は共通していそうですよね。では、「人」は「骨」を継承すべきなのでしょうか?
先ほどの継承でも説明しましたが、継承は「is-a」関係の時に使うものです。「人は骨である」と言えるかどうか考えるわけです。考えるまでもなく、答えはノーです。
しかし、「骨は人の一部である」とか「魚は骨を持っている」とかいうことはできそうです。このように「BはAを持っている(含んでいる)」というような関係を包含関係とか「has-a」関係などと言います。
包含でも、クラスAの特性をクラスBで利用することができます。しかし、クラス間の依存度は、継承に比べれば小さいです。
具体的な使い方は、次の記事で説明したいと思います。
Python入門 - クラス その2
クラス変数
インスタンス変数は、生成されたオブジェクトごとの変数で、別オブジェクトの変数なら、完全に独立した変数でした。
Pythonでは、このインスタンス変数とは別に、オブジェクトではなくクラスに属する変数を作ることもできます。これを「クラス変数」と言います。クラス変数は同じクラスのオブジェクトの間で共有されます。また、オブジェクトを生成しなくてもクラスからアクセスできます。
書式
class クラス名:
クラス変数 = 値
サンプルコード
class MyClass:
value = 100
def plus(self, x):
MyClass.value += x
print(MyClass.value)
print(MyClass.value)
test1 = MyClass()
test2 = MyClass()
test1.plus(100)
test2.plus(50)
実行結果
100
200
250
別々に作成したオブジェクトのインスタンスメソッドで個別に数値を足しています。足し算の結果が、オブジェクトごとに別々にならず、累積していっているのがわかると思います。
クラスメソッド
インスタンス変数、インスタンスメソッド、クラス変数ときて、最後にクラスメソッドを紹介したいと思います。
クラスメソッドも、クラス変数と同じでオブジェクトを生成しなくても、クラス名から利用することができます。
書式
class クラス名:
@@classmethod
def クラスメソッド名(cls, 引数):
クラスメソッドの処理
クラスメソッドの処理
・・・
サンプルコード
class MyClass:
value = 100
def plus(self, x):
MyClass.value += x
print(MyClass.value)
@classmethod
def minus(cls, x):
cls.value -= x
print(cls.value)
print(MyClass.value)
MyClass.minus(10)
実行結果
100
90
クラスメソッドの第一引数は「cls」とします。インスタンスメソッドの「self」と同じで、クラス自身を表していてclsを利用してクラス変数や、クラスメソッドを利用することができます。呼び出す時には、自動的に渡される省略するところも一緒です。
クラスメソッド内では、インスタンス変数を使うことはできません。インスタンス変数はオブジェクトを生成して初めて作られるものです。そのため、オブジェクトを生成しなくても利用できるクラスメソッドの中ではインスタンス変数を利用できないのです。
ちなみに、selfと一緒でclsという名前でないといけないわけではありません。しかし、clsdとするのが暗黙のルールです。
なお、「@・・・」を「デコレータ」と言います。
スタティックメソッド
クラスメソッドに似ているメソッドに「スタティックメソッド」があります。
書式
class クラス名:
@staticmethod
def スタティックメソッド名:
スタティックメソッドの処理
スタティックメソッドの処理
・・・・
サンプルコード
class MyClass:
value = 100
def plus(self, x):
MyClass.value += x
print(MyClass.value)
@classmethod
def minus(cls, x):
cls.value -= x
print(cls.value)
@staticmethod
def devide(x):
MyClass.value /= x
print(MyClass.value)
print(MyClass.value)
MyClass.devide(5)
実行結果
100
20.0
クラスメソッドとの違いは、引数でclsを渡すかどうかだけです。clsを渡さないため、スタティックメソッドでクラス変数を利用しようと思うと、クラス名からアクセスしないといけません。
クラスメソッドとスタティックメソッドとの動作の違いについては、別の記事で解説しようと思います。
アクセス制限
クラスの変数やメソッドの中には、クラスの外部から利用して欲しくないものもあるかもしれません。また、クラスを利用する側から見てもクラスの内部で使われているだけで、使う人に関係のないものは見えない方が、間違って使ったり、使い方に迷ったりしにくいです。
そこで、Pythonでは、クラス外部から簡単にはアクセスできないようにすることができます(Javaなどのように完全に制限することはできません)。
この機能を使うには「__(アンダースコア2つ)」を変数名やメソッド名の前につけます
書式
class クラス名:
__クラス変数
def __init__(self):
self.__インスタンス変数 = 値
・・・
def __インスタンスメソッド名():
・・・
@classmethod
def __クラスメソッド名():
・・・
@staticmethod
def __スタティックメソッド名():
・・・
サンプルコード
class MyClass:
def __init__(self):
self.__private2 = 5.5
def plus(self, x):
self.__private2 += x
self.__show()
def __show(self):
print(self.__private2)
test = MyClass()
test.plus(10)
test.__show()
実行結果
15.5
Traceback (most recent call last):
File "/Users/hiroyuki-narita/Desktop/MyDocs/Python3/moduleTest.py", line 14, in
test.__show()
AttributeError: 'MyClass' object has no attribute '__show'
実行結果を見るとわかるように、クラスの外側からは「__show」が存在しないように見えています。そのため、「__show」を使うことができません。しかし、インスタンスメソッドの中、つまり、クラス定義の中では通常通り「__show」を使うことができます。これがアクセス制限です(ただし、実は特殊な書き方をすることで、__showをクラスの外側から呼び出すことができてしまいます)。
また、変数名やメソッド名の頭に「_(アンダースコア1つ)」をつけると、暗黙のルールで「クラスの外側では勝手に使わないでね」という意味になります。これはPythonの機能上の話ではなく、あくまでプログラマの間の紳士協定のようなものです。
Python入門 - クラス その1
オブジェクト指向とは何か?
Pythonではオプジェクト指向プログラミングをサポートしています。オブジェクト指向と言葉にするのは簡単なのですが、そもそもオブジェクト指向とはなんなのでしょうか?
簡単に説明すると、「ひとかたまりのデータと機能をまとめた設計図」を用意して、その設計図をもとに「オブジェクト(インスタンスとも言う)」を生成する、と言う内容です。この、「ひとかたまりのデータと機能をまとめた設計図」のことをクラスと言います。
もう少し具体的にクラスとオブジェクトについて説明したいと思います。例えば、車クラスを考えてみます。車には、「エンジン」とか「タイヤ」と言った部品からできています。この部品がクラスのデータに当たります。また、車クラスには「走る」「止まる」と言うような機能もあります。
この車クラスは、まだ設計図でしかありません。そこで、この車クラス(設計図)を利用して、実際に車を作ろうと思います。これを「オブジェクトを生成する」とか「インスタンス化する」と言います。基本的には、実際に車を作ることで初めて「走る」「止まる」と言った機能を利用することができます。また、実際の車ごとにエンジンやタイヤは別々に生成できます(全てのオブジェクトに共通するデータや機能もあります)。ガソリンの量なんかは走った量によって車ごとに違うかもしれませんね。
また、車クラスの部品であるエンジンも、実際にはピストンやシリンダーと言った部品を持つクラスであるといえます。
このように、プログラムを構成する基本的な要素である、「データ」と「機能(関数)」を「クラス」と「オブジェクト」で考えていくことが、オブジェクト指向プログラミングです。
なお、データと機能は、状態と振る舞いと言ったりもします。
クラスはオブジェクト指向の核心的な要素であり、様々な考え方や使い方があります。そのため、一度に説明しきることは難しいので少しずつみていきたいと思います。
インスタンスメソッドを使う
それでは、早速クラスを使ってみましょう。
書式
#クラスの定義
class クラス名:
def メソッド名(self):
メソッドの処理
メソッドの処理
・・・
#クラスの生成
変数 = クラス名()
サンプルコード
class car:
def run(self):
print('run!')
def stop(self):
print('stop!')
test = car()
test.run()
test.stop()
実行結果
run!
stop!
先ほど説明したクラスの機能(関数)のことを「メソッド」と言います。特に、オブジェクトを生成してから使うメソッドを「インスタンスメソッド」と言います。
クラスの定義では、インスタンスメソッドの引数に「self」がありますが、実際に呼び出すときには、何も引数を渡していません。
とりあえず、インスタンスメソッドを定義する時には、最初の引数にselfと書くんだと思っておきましょう。
コンストラクタ
オブジェクトが生成される時に1度だけ実行される特殊なメソッドのことを、コンストラクタと言います。
書式
class クラス名:
def __init__(self):
コンストラクタの処理
コンストラクタの処理
・・・
サンプルコード
class car:
def __init__(self):
print('create!')
def run(self):
print('run!')
def stop(self):
print('stop!')
test = car()
test.run()
test.stop()
実行結果
create!
run!
stop!
コンストラクタの処理が、オブジェクトを生成する時に実行されていることがわかると思います。コンストラクタでは、一般的にオブジェクトの初期化処理をすることができます。
インスタンス変数
オブジェクトを生成すると、オブジェクト内に作られる変数のことを「インスタンス変数」と言います。インスタンス変数はオブジェクトごとに別々のデータです。その定義は、コンストラクタの中でselflを使って行います。
書式
class クラス名:
def __init__(self):
self.インスタンス変数 = 値
変数 = クラス名()
変数.インスタンス変数
サンプルコード
class car:
def __init__(self):
print('create!')
self.gas = 100
def run(self):
print('run!')
def stop(self):
print('stop!')
test = car()
test.run()
test.stop()
print(test.gas)
実行結果
create!
run!
>stop!
100
このように、インスタンス変数をオブジェクトから使うことができます。また、インスタンス変数は、インスタンスメソッド内でもselfを利用して使うことができます。
書式
class クラス名:
def __init__(self):
self.インスタンス変数 = 値
def メソッド名(self):
self.インスタンス変数
サンプルコード
class car:
def __init__(self):
print('create!')
self.gas = 100
def run(self, x):
print('run!')
self.gas -= x
print(self.gas)
def stop(self):
print('stop!')
test = car()
test.run(10)
test.run(5.5)
実行結果
create!
run!
90
run!
84.5
self
ここで、少しselfについて説明しようと思います。selfはコンストラクタ、インスタンスメソッドに必ず必要な引数で、オブジェクト自分自身を表す特殊なものです。定義をする時には書く必要があるのですが、呼び出す時には自動的に渡されるため、書きません。
そして、このselfを通じで自分自身のインスタンス変数やインスタンスメソッドを呼び出すことができる、という仕組みです。
Python入門 - モジュールとパッケージ
モジュールの利用
色々なアプリで共通して利用する関数などを、別ファイルにまとめることで再利用できるようにしたものを、Pythonでは「モジュール」と呼びます。自分でモジュールを作成することもできますし、Pythonに初めから付属している「標準モジュールライブラリ」を利用することもできます。
まずは、標準モジュールライブラリの使い方から説明します。
import
モジュールを利用するためには、利用したいモジュールを「インポート」する必要があります。早速、標準モジュールをインポートしてみましょう。
書式
import モジュール名
モジュール名.関数名
サンプルコード
import math
print(math.sin(3.14 / 2))
print(math.log10(1000))
print(math.fabs(-10.33))
実行結果
0.9999996829318346
3.0
10.33
標準モジュールの1つである「math」をインポートすることで、mathの関数を利用することができます。ここでは三角関数sinを計算する「sin」、10を底とする対数関数を計算する「log10」、絶対値を計算する「fabs」を使っています。
Pythonには膨大な量の標準ライブラリが、初めから用意されています。どんなアプリを作るにもよく利用するような機能がすでにあるということです。そのため、プログラマは自分が独自にやりたいことに、よりエネルギーを向けることができるのです。
全ての標準ライブラリを紹介することはできません。数が多すぎるからです。リファレンスが用意されているので、これを利用するようにしましょう。
日本語:Python 標準ライブラリ
英語:The Python Standard Library
次に、モジュールの一部の関数だけインポートする方法を説明します。
書式
from モジュール名 imort 関数名
関数名
サンプルコード
from math import sin
print(sin(3.14))
実行結果
0.0015926529164868282
mathの中の「sin」しかインポートしない代わりに、sinの頭に、「math.」をつけなくても利用することができます。
モジュールの作成
次に、自分で独自にモジュールを作成して利用する方法について説明します。myModule.pyとmoduleTest.pyは同じフォルダに格納しましょう。
サンプルコード(myModule.py)
def calcLine(x):
y = 10 * x - 5
return (x, y)
サンプルコード(moduleTest.py)
import myModule
print(myModule.calcLine(3.3))
実行結果
(3.3, 28.0)
インポートするときには、「.py」は書きません。
__name__ == " __main__"
さて、自分で作成したモジュールを、他のpyファイルから呼び出すときは問題ないのですが、モジュールそのものを直接実行した時はどうでしょうか。
直接実行されたときにだけ処理されるプログラムを書くためには、次のようにします。
サンプルコード(myModule.py)
def calcLine(x):
y = 10 * x - 5
return (x, y)
if __name__ == "__main__":
print(calcLine(123.45))
実行結果
(123.45, 1229.5)
「__name__」( "__" は "_" アンダースコア2つ )は、デフォルトで定義されている変数です。この__name__には自動で値が代入されるのですが、直接実行されたときには、「"__main__"」が代入されています。そこで、「if __name__ == "__main__"」とすることで、直接実行されたときだけ実行されるプログラムを書くことができます。
パッケージ
いくつかモジュールを作成すると、わかりやすくするために、モジュールを分類したくなってきます。また、何人かで別々にモジュールを作成していると、うっかり同じ名前の関数を作ってしまったりします。
このようなことを解決するために、Pythonには「パッケージ」という機能があります。いわゆる名前空間です。
moduleTest.pyのあるフォルダ内に、myPackageというフォルダを作成し、その中にmodule1.pyというpyファイルを作成します。また、同様にmyPackageフォルダ内に__imit__.pyという空のpyファイルを作成します。これで準備完了です。
サンプルコード(moduleTest.py)
import myPackage.module1
help(myPackage.module1)
print(myPackage.module1.calcPolar(1, 1))
サンプルコード(module1.py)
import math
def calcPolar (x, y):
distance = pow(x**2 + y**2, 0.5)
return (distance, math.atan(y / x))
実行結果
Help on module myPackage.module1 in myPackage:
NAME
myPackage.module1
FUNCTIONS
calcPolar(x, y)
FILE
XXXXXXXXXXXXX/myPackage/module1.py
(1.4142135623730951, 0.7853981633974483)
無事にパッケージ内のモジュールの関数を呼び出すことができました。パッケージの書き方は、フォルダ構成を順番に「. (ドット)」でつなげるだけです。
また、「help」はモジュールのヘルプ情報を表示してくれます。
パッケージを利用するには、パッケージがどこに置いてあるのか pythonが知っている必要があります。myPackageをmoduleTest.pyと同じフォルダに置いたのは、実行されているpyファイルのフォルダは、pythonが知っているからです。
もし、全然別の場所にパッケージを置きたい場合は次のようにして、pythonにパッケージの場所(パス)を指定します。
サンプルコード
import sys
sys.path.append('XXXXXXXXXXX')
このように、sys.pathにパッケージのパスを追加します。
Python入門 - 関数
関数を使う
プログラムをしていると、同じような処理を何度も使うシーンが出てきます。
サンプルコード
print('process A')
print('process B')
print('process C')
print('process A')
print('process B')
print('process C')
実行結果
process A
process B
process C
process A
process B
process C
このように、何かひとまとまりの処理を何度か使うような場合、「関数」にすることで、便利に使うことができます。
サンプルコード
def funcTest():
print('process A')
print('process B')
print('process C')
funcTest()
funcTest()
実行結果
process A
process B
process C
process A
process B
process C
関数の最も基本的な書き方は、以下のようになります。
また、関数を使うことを「関数を呼び出す」と言ったりもします。
def 関数名():
実行したい処理
実行したい処理
・・・
引数
関数を呼び出すときに、関数内で使うオブジェクトを関数に渡すことができます。つまり、渡すオブジェクトによって関数の処理を変えることができます。
次のサンプルを見てみましょう。
サンプルコード
def funcTest(value):
if(value < 0):
print('do not calc')
else:
print('calc')
print(10 * value - 5)
funcTest(5.5)
funcTest(-3)
実行結果
calc
50.0
do not calc
このように、関数に渡すオブジェクトのことを「引数(ひきすう)」と言います。聞きなれない言葉だと思いますが、「ふーん、そういう用語なんだ」と考えておけばいいと思います。
引数は、たくさん渡すこともできます。
サンプルコード
def funcTest(value, a, b):
if(value < 0):
print('do not calc')
else:
print('calc')
print(a * value - b)
funcTest(5.5, 10, -5)
funcTest(30, -5.5, 10)
実行結果
calc
60.0
calc
-175.0
引数には、どのようなオブジェクトでも渡すことができます。しかし、正しく処理できないオブジェクトを渡すと、プログラムを実行したときにエラーになってしまいます。
サンプルコード
def funcTest(value, a, b):
if(value < 0):
print('do not calc')
else:
print('calc')
print(a * value - b)
funcTest(5.5, '10', -5)
実行結果
calc
Traceback (most recent call last):
File "XXXX.py", line 9, in
funcTest(5.5, '10', -5)
File "XXXX.py", line 7, in funcTest
print(a * value - b)
TypeError: can't multiply sequence by non-int of type 'float'
「ファイルXXXX.pyの9行目の"funcTest(5.5, '10', -5)"の中の、"print(a * value - b)"でエラーが発生した」という話の後に、「can't multiply sequence by non-int of type 'float」 ということで、掛け算ができないよというエラー内容になります。
関数の引数は正しく処理できるものを渡すようにしましょう。(ただし、実行中にエラーが発生した場合の対策として、例外処理があります。別の記事で解説することになると思います)
return文
今まで見てきた関数のサンプルでは、一度関数の処理が終わると、元の処理にただ戻るだけでした。しかし、関数で処理した結果を元の処理に返したいシーンもあります。j例えば、ある計算をする関数で、計算結果を元の処理に返したいような場合です。
Pythonではreturn文を使うことで、オブジェクトを返すことができます。
サンプルコード
def funcTest(value, a, b):
print('calc')
ret = a * value - b
return ret
ret = funcTest(10, 5, -3.3)
print(ret)
実行結果
calc
53.3
このように、関数から返ってきたオブジェクトのことを「返り値」とか、「戻り値」と呼びます。
もし、いくつかのオブジェクトを返したいときは、タプルを利用することを検討して見ましょう。
サンプルコード
def funcTest(value, a, b):
print('calc')
ret1 = a * value - b
ret2 = b * value + a
return (ret1, ret2)
ret = funcTest(10, 5, -3.3)
print(ret)
実行結果
calc
(53.3, -28.0)
それでは、最後に関数の書き方をまとめておきます。
def 関数名(引数1, 引数2, ・・・):
実行したい処理
実行したい処理
・・・
return 返り値
Python入門 - 繰り返し
同じ処理をなんども繰り返す
学生の名前データをリストにしている時に、リストに名前をある1つずつ順番に表示するような処理を考えてみましょう。
サンプルコード
studentList = ['Suzuki', 'Tanaka', 'Kato', 'Yamada']
print(studentList[0])
print(studentList[1])
print(studentList[2])
print(studentList[3])
実行結果
Suzuki
Tanaka
Kato
Yamada
リストの要素数が少なければ、こういうやり方でもいいかもしれません。
しかし、100人分の名前のリストだったらどうでしょうか?この書き方では、正直ちょっとやってられないですね。
このやりたいことは、「リストの要素を表示する」という処理をリストの要素数だけ繰り返す、という操作です。
このように、同じ処理を繰り替えず(ループする)ためにPythonでは、「for文」と「while文」というものがあります。
for文
それでは、先にfor文からみていきましょう。
for文は「オブジェクトの最初の要素から処理をスタートして、最後の要素の処理が終わるまで、処理を繰り返す」ことができます。
for ループ変数 in オブジェクト:
繰り返したい処理
繰り返したい処理
・・・
まず、繰り返したい処理をforよりも一段下げる(インデントする)ことと、forの最後に「:(コロン)」を付けるのは、if文と一緒です。
「ループ変数」と「オブジェクト」については、サンプルコードをみながら説明したいと思います。
サンプルコード
sutudentList = ['Suzuki', 'Tanaka', 'Kato', 'Yamada']
for name in sutudentList:
print(name)
実行結果
Suzuki
Tanaka
Kato
Yamada
先ほどの、1つずつ順番に表示したサンプルコードと同じ結果になりました。
これは、ループ変数「name」にオプジェクト「studentList」の要素を、順番に代入しながら処理をしたからです。
ループ変数には、オブジェクトの要素が代入されます。
そして、ループが1回分が終わると、オブジェクトの次の要素がループ変数に代入されます。
この「オブジェクトの要素を順番にループ変数に代入して処理」することを「オブジェクトの最後の要素まで(オブジェクトの全ての要素に対して)」行います。
これが、for分の基本的な使い方です。
では、もう少しサンプルをみてみましょう。
サンプルコード
drinkSet = (['water', 'coffee', 'tea'])
for drink in drinkSet:
if drink == 'coffee':
print('I like ' + drink)
elif drink == 'tea':
print('I do not like ' + drink)
実行結果
I like coffee
I do not like tea
このように、ifと組み合わせて使うこともできます。
繰り返し処理は、実際のプログラムの中でも、よくでてきますし、様々な使い方があります。
rangeオプジェクト
繰り返し処理をする時に、リストやセットの全ての要素について処理するのではなく、「10回繰り返す」とか「-5〜5まで繰り返す」ということをしたい時があります。
この時に、例えば、list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]というオブジェクトを作ればできるのですが、めんどくさいです。
このような数字が順番に並んだオブジェクトを簡単に作る方法がPythonにはあります。
それが「rangeオブジェクト」です。
サンプルコード
sum = 0
for i in range(10):
print(i)
sum += i
print(sum)
print('**************')
for i in range(-5,5):
print(i)
実行結果
0
0
**************
1
1
**************
2
3
**************
3
6
**************
4
10
**************
5
15
**************
6
21
**************
7
28
**************
8
36
**************
9
45
**************
-5
-4
-3
-2
-1
0
1
2
3
4
range(n)で「0 〜 (n - 1)までのn個の整数」が要素のオブジェクトになります。
また、range(from, to)で「from 〜 (to - 1)までの整数」が要素のオブジェクトになります。
rangeは、指定回数だけ順番に繰り返し処理をする時によく使います。
continue文
処理を繰り返している途中で、ある条件の時だけ、処理をスキップしたい場合があります。この時、continue文を使うことで処理をスキップすることができます。
次のサンプルは3の倍数の時だけ、数値を表示するのをスキップするプログラムです。
サンプルコード
for i in range(10):
if (i % 3) == 0:
print('skip!')
continue
print(i)
実行結果
skip!
1
2
skip!
4
5
skip!
7
8
skip!
continueは、たいていの場合、if文と組み合わせて使うことになると思います。
break文
処理のスキップに続いて、繰り返しの中断の仕方もみてみましょう。
例えば、「繰り返し処理をしている中で、エラーが発生したら繰り返しを中断する」などの使い方があります。繰り返しの中断には「break文」を利用します。
次のコードは5〜19までの数値を順番に足していく中で、「もし100を超えたら繰り返しを中断」します。
サンプルコード
sum = 0
for i in range(5, 20):
sum += i
print(sum)
if sum > 100:
print('finish!')
break
実行結果
5
11
18
26
35
45
56
68
81
95
110
finish!
繰り返しが途中で中断していることがわかりますね。
whilw文
ythonには、もう1種類、繰り返しをするために「while文」があります。
while文は「条件がtrueである間、処理を繰り返す」ことができます。
while 条件式:
繰り返したい処理
繰り返したい処理
・・・
では、実際にコードを書いてみましょう。
サンプルコード
i = 0
while i < 10:
i += 2
print(i)
実行結果
2
4
6
8
10
while文では、for文と違い、事前に繰り返し回数がわからないような処理に向いています。for文では「オブジェクトの要素数の分しか繰り返さない」のに対して、while文では、「条件がtrueの間(つまり、falseになるまで)ずっと繰り返す」からです。
while文でも、for文と同じようにcontinue分野break文を使うことができます。
無限ループ
while文の特徴的な使い方の1つに無限ループがあります。これは、while文の条件が、ずっとtrueのままでfalseにならないようにすることで実現できます。
次のコードは、無限ループなので、実行すると普通にはプログラムは終了しません。強制的に中断するためには、キーボードの「control + c」を同時におす必要があります。(IDLEを終了してもOKです)
サンプルコード
i = 0
while i < 10:
print('loop!ç')
whileの中で、「i」が変更されないので、「iはずっと0のまま」です。その結果「i < 10はずっとtrue」でループから抜け出すことができません。しかし、この無限ループはbreakと組み合わせて、便利に使うことができます。
次のサンプルは、endと入力してenterキーが押されるまでループします。(input()を使うことで、キーボードからの入力を取得することができます)
サンプルコード
while True:
print('loop!')
str = input()
if str == 'end':
print('break!')
break
Python入門 - 条件分岐
もし〇〇だったら、・・・する
今まで、数値や文字列を、1行ずつ別々に実行してきました。
しかし、実際のプログラムでは
「まず、これをして、次にあれをして、その結果がこれこれだったら、それをして・・・」
というように、上から順番にプログラムを実行していって、条件によって処理を分岐させたりします。
今回は、条件によって処理を分岐させる「if文」について説明していきます。また、ここからはインタラクティブモードではなく、pyファイルにプログラムしていきます。
if文
条件分岐するためには、if文を使います。
if 条件式:
条件が真の時、実行する処理
・・・
サンプルコード
num = 10
if num < 100:
print('num is small')
実行結果
num is small
ifの後に「条件」を記述し、その下の行から「条件が真の時だけ実行する処理」を書きます。
この「条件が真の時だけ実行する処理」はifに比べて1段下げます。これは、実はとても重要な意味があり、なくてはならないもので、「インデント」と言います。この「インデント」によって、その処理がif文の中の処理だということがわかるのです。
例えば、次のような処理を見てみましょう。
サンプルコード
num = 1000
if num < 100:
print('num is small')
print('always!')
実行結果
always!
このようにprint('always!')はインデントされていないため、if文の中に入っていません。そのため、条件の真偽に関係なく、必ず実行されてしまいます。
インデントされたいくつかの処理のまとめることができます。これをブロックと言います。
サンプルコード
num = 1000
if num < 100:
print('num is small')
print(num)
if num >= 100:
print('num is big!')
print(num)
print('alwasys!')
実行結果
num is big!
1000
alwasys!
if else文
「もし条件が真なら・・・して、そうでなければ・・・する」という処理をするのが、「if else文」です。
サンプルコード
num = 1000
if num < 100:
print('num is small')
print(num)
else:
print('num is big')
print(num)
print('alwasys!')
実行結果
num is big
1000
alwasys!
if else文ではifブロックかelseブロックのどちらか1つが、必ず実行されます。
if elif else文
if else文をさらに進めて「もし条件1なら・・・、そうでなくて条件2なら・・・、そうでなければ・・・」という処理をするのが「if elif else文」です。
サンプルコード
str = 'triangle'
if str == 'circle':
print('circle')
elif str == 'triangle':
print('triangle')
else:
print('other')
実行結果
triangle
この例では、elifブロックは1つしかないですが、たくさんあってもOKです。また、elseブロックがなくても問題ありません。
この「if elif else文」では、注意しておいた方がいいことがあります。それは、上の条件から順番に確認していって、該当する条件が見つかったら、それ以降の条件で真になるものがあっても無視される、ということです。
サンプルコード
num = 5
if num > 10:
print('5 - ')
elif 3 < num and num <= 10 :
print('3 - 10')
elif -5 < num and num <= 7:
print('-5 - 7')
else:
print('- -5')
実行結果
3 - 10
条件としては「3 < num and num <= 10」でも「-5 < num and num <= 7」でも真ですが、先にある方のブロックだけ実行されます。
ネスト
最後に、ネストについて説明します。これはインデントと同じでif文に限らず、他のものにも同様な考え方です。
インデントされたブロックの中で、さらにインデントします。
サンプルコード
num = 5
str = 'circle'
if num > 10:
print('5 - ')
elif 3 < num and num <= 10 :
print('3 - 10')
if str == 'circle':
print('Tlhis is circle')
else:
print('This is not circle')
elif -5 < num and num <= 7:
print('-5 - 7')
else:
print('- -5')
実行結果
3 - 10
Tlhis is circle