Object-oriented Programming / Exception handling

Post on 14-Jul-2015

220 views 1 download

Tags:

Transcript of Object-oriented Programming / Exception handling

1

Object-oriented Programming(OOP) / Object-oriented Programming(OOP) / Exception handlingException handling

2

OutlineOutline

1. 0. Object-oriented Programming- What is OOP?- What is OOP?

1. 1. 1. 1. Features of OOPFeatures of OOP- Inheritance(- Inheritance(継承継承))- Polymorphism(- Polymorphism(多態性多態性))- Dynamic binding(- Dynamic binding(動的束縛動的束縛))- Encapsulation(- Encapsulation(カプセル化カプセル化))

1. 2. 1. 2. Exception handlingException handling

1. 3. 1. 3. AppendixAppendix

3

IntroductionIntroduction

Object-oriented Programming (OOP)Object-oriented Programming (OOP)::a programming paradigm that represents a programming paradigm that represents concepts as "concepts as "objectsobjects" that have data fields " that have data fields ((attributesattributes that describe the object) and that describe the object) and associated procedures known as associated procedures known as methodsmethods..(from Wikipedia “Object-oriented programming” (at 2013/05/11))(from Wikipedia “Object-oriented programming” (at 2013/05/11))

属性属性ととメソッドメソッドからなるからなるオブジェクトオブジェクトで概念を表現で概念を表現 オブジェクト間のオブジェクト間の相互作用相互作用としてプログラムを実装としてプログラムを実装 多くのプログラミング言語では、オブジェクトは多くのプログラミング言語では、オブジェクトはクラスクラスののインスタンスインスタンスとして実装として実装

message

message

object A:

m1

m2

a2

a1

object B:

m1

m2

a2

a1

4

OOP vs Structured ProgrammingOOP vs Structured Programming

Structured Programming Language(like C, php, ...)Structured Programming Language(like C, php, ...)

OOP Language(like Java, Python, ...)OOP Language(like Java, Python, ...)

data1:........................

f1

data2:........................

f0

f2

int main()

O1

O0

O2

data is recorded asattribute inside object

O3

5

Class definition in PythonClass definition in Python

右のコードでは、クラス右のコードでは、クラスdogdogを定義を定義

__init____init__は特殊なメソッドは特殊なメソッドで、クラスのインスタンスで、クラスのインスタンスが生成されるときに呼ばれが生成されるときに呼ばれるる((constructor))。。

PythonPythonでは、メソッドのでは、メソッドの引数の最初は必ず引数の最初は必ずselfselfで、で、selfselfはそのインスタンス自はそのインスタンス自身身(momo(momoなどなど))を表す特殊を表す特殊な引数。な引数。

ここでは、ここでは、momo, kuromomo, kuroははクラスクラスdogdogののinstance。

classclass dog(object): dog(object): # constructor# constructor defdef __init____init__(self, name):(self, name): self.name = nameself.name = name # deconstructor# deconstructor defdef __del____del__(self):(self): passpass

defdef getNamegetName(self):(self): print “this is “ + self.nameprint “this is “ + self.name

>>> momo = dog(“Momo”)>>> momo = dog(“Momo”)>>> momo.getName()>>> momo.getName()this is Momothis is Momo

>>> kuro = dog(“Kuro”)>>> kuro = dog(“Kuro”)>>> kuro.getName()>>> kuro.getName()this is Kurothis is Kuro

6

OutlineOutline

1. 0. 1. 0. Object-oriented ProgrammingObject-oriented Programming- What is OOP?- What is OOP?

1. 1. Features of OOP- Inheritance(- Inheritance(継承継承))- Polymorphism(- Polymorphism(多態性多態性))- Dynamic binding(- Dynamic binding(動的束縛動的束縛))- Encapsulation(- Encapsulation(カプセル化カプセル化))

1. 2. 1. 2. Exception handlingException handling

1. 3. 1. 3. AppendixAppendix

7

Inheritance(Inheritance(継承継承))

既存のクラスにメソッドを付け足したり、メソッドの動作既存のクラスにメソッドを付け足したり、メソッドの動作を書き換えたりを書き換えたり((override))した新しいクラスを作成した新しいクラスを作成

コードをコピーして別のクラスを作るよりも、コードをコピーして別のクラスを作るよりも、 コードが短くなるコードが短くなる コードのメンテナンスが簡単になるコードのメンテナンスが簡単になる コードを理解しやすくなるコードを理解しやすくなる

自作のクラスだけでなく、プログラミング言語に組み込ま自作のクラスだけでなく、プログラミング言語に組み込まれているクラスも継承可能れているクラスも継承可能

言語によっては、複数のクラスを継承することも可能言語によっては、複数のクラスを継承することも可能((多重継承))

8

Inheritance(Inheritance(継承継承))

「モモ」は柴犬、「クロ」「モモ」は柴犬、「クロ」はレトリーバーとすると、はレトリーバーとすると、「モモ」はクラス「モモ」はクラスshibashibaの、「クロ」はクラスの、「クロ」はクラスretrieverretrieverのインスタンスのインスタンス

shibashibaももretrieverretrieverももdogdogのの一種一種

classclass dog(object): dog(object): # constructor# constructor defdef __init____init__(self, name):(self, name): self.name = nameself.name = name defdef getNamegetName(self):(self): print “this is “ + self.nameprint “this is “ + self.nameclassclass shiba(dog): shiba(dog): defdef __init____init__(self, name):(self, name): self.name = name + “(s)”self.name = name + “(s)”classclass retriever(dog): retriever(dog): passpass

>>> momo = shiba(“Momo”)>>> momo = shiba(“Momo”)>>> momo.getName()>>> momo.getName()this is Momo(s)this is Momo(s)>>> kuro = retriever(“Kuro”)>>> kuro = retriever(“Kuro”)>>> kuro.getName()>>> kuro.getName()this is Kurothis is Kuro

dog

shiba retriever

object

momo kuro

9

Inheritance(Inheritance(継承継承))

「モモ」と「クロ」の子ど「モモ」と「クロ」の子ども「ポチ」は雑種も「ポチ」は雑種ZZ。。

多重継承を使えば、雑種も多重継承を使えば、雑種も表現可能。表現可能。

classclass shiba(dog): shiba(dog): defdef __init____init__(self, name):(self, name): self.name = name + “(s)”self.name = name + “(s)”

classclass retriever(dog): retriever(dog): passpassclassclass Z(shiba, retriever): Z(shiba, retriever): passpass

>>> momo = shiba(“Momo”)>>> momo = shiba(“Momo”)>>> momo.getName()>>> momo.getName()this is Momo(s)this is Momo(s)>>> kuro = retriever(“Kuro”)>>> kuro = retriever(“Kuro”)>>> kuro.getName()>>> kuro.getName()this is Kurothis is Kuro>>> pochi = Z(“Pochi”)>>> pochi = Z(“Pochi”)>>> pochi.getName()>>> pochi.getName()this is Pochi(s)this is Pochi(s)

dog

shibainu retriever

object

momo kuroZ

pochi

10

Polymorphism(Polymorphism(多態性多態性,,多相性多相性))

CC言語のようなオブジェクトの概念がない言語では、例え言語のようなオブジェクトの概念がない言語では、例えば各種の型の変数を文字列に変換したいとき、ば各種の型の変数を文字列に変換したいとき、IntToString()IntToString()ややFloatToString()FloatToString()のように、型によって関のように、型によって関数を使い分けなければいけない数を使い分けなければいけない((同じ名前の関数を複数定義同じ名前の関数を複数定義することができないすることができない))。。

オブジェクト指向であれば、オブジェクトごとに同じ名前オブジェクト指向であれば、オブジェクトごとに同じ名前のメソッドが定義できるので、同じのメソッドが定義できるので、同じ((類似の類似の))操作を行うた操作を行うためにめに統一的な名称統一的な名称を用いることができる。を用いることができる。

あくまで、同じ名前を使えるのでコーディング効率が上があくまで、同じ名前を使えるのでコーディング効率が上がるというだけの話。当然、るというだけの話。当然、実装はオブジェクト毎実装はオブジェクト毎に別個にに別個にしなければならない。しなければならない。

11

Polymorphism(Polymorphism(多態性多態性,,多相性多相性))

classclass yukirin(object): yukirin(object): defdef catchphrasecatchphrase(self):(self): return “return “寝ても覚めてもゆきりんワールド寝ても覚めてもゆきりんワールド!”!”

classclass mayuyu(object): mayuyu(object): defdef catchphrasecatchphrase(self):(self): return “return “み~んなの目線を、いただきまゆゆ~♪”み~んなの目線を、いただきまゆゆ~♪”

>>> m = mayuyu()>>> m = mayuyu()>>> y = yukirin()>>> y = yukirin()>>> # >>> # 相手がゆきりんでもまゆゆでも同じメソッドを呼べば相手がゆきりんでもまゆゆでも同じメソッドを呼べばOK!OK!>>> m.catchphrase()>>> m.catchphrase()>>> y.catchphrase()>>> y.catchphrase()

12

Dynamic binding(Dynamic binding(動的束縛動的束縛))

コンパイルを行わないインタプリタ型言語の場合、事前にコンパイルを行わないインタプリタ型言語の場合、事前にプログラムの正しさをチェックせず、いきなり実行する。プログラムの正しさをチェックせず、いきなり実行する。

そのため実行する段階で初めて、変数の型やオブジェクトそのため実行する段階で初めて、変数の型やオブジェクトが確定するが確定する((動的型付け))。。

PolymorphismPolymorphismによりメソッドに統一的な名称を使えるのによりメソッドに統一的な名称を使えるので、変数の型が確定しなくても、オブジェクトが必要なメで、変数の型が確定しなくても、オブジェクトが必要なメソッドを持ってさえいれば、関数を書くことができる。ソッドを持ってさえいれば、関数を書くことができる。

13

Dynamic binding(Dynamic binding(動的束縛動的束縛))

# member# memberにどんなオブジェクトが渡されるかは不明だが、にどんなオブジェクトが渡されるかは不明だが、# catchphrase# catchphraseというメソッドを持ってさえいれば、適切に対応できる。というメソッドを持ってさえいれば、適切に対応できる。defdef print_catchphraseprint_catchphrase(member):(member): return member.catchphrase()return member.catchphrase()

>>> m = mayuyu()>>> m = mayuyu()>>> print_catchphrase(m)>>> print_catchphrase(m)((省略省略))>>> m = mariko()>>> m = mariko()>>> print_catchphrase(m)>>> print_catchphrase(m)((省略省略))>>> m = momokuro()>>> m = momokuro()>>> print_catchphrase(m)>>> print_catchphrase(m)今、会えるアイドル、週末ヒロイン。今、会えるアイドル、週末ヒロイン。

14

Encapsulation(Encapsulation(カプセル化カプセル化))

オブジェクトが持つ属性やメソッドに、外部からのアクセオブジェクトが持つ属性やメソッドに、外部からのアクセスを許可するかを設定。スを許可するかを設定。

多くの言語では、多くの言語では、public, protected, privatepublic, protected, privateのの33段階。段階。public::オブジェクトの外部からアクセス可能。オブジェクトの外部からアクセス可能。protected::オブジェクト自身と、自身を継承したオブジェクトからのオブジェクト自身と、自身を継承したオブジェクトからのみアクセス可能。みアクセス可能。private::オブジェクト自身オブジェクト自身((内部内部))からのみアクセス可能。からのみアクセス可能。

PythonPythonでは、では、_(underscore)_(underscore)で始まるメソッド・属性はで始まるメソッド・属性はprivate(private(ということになっているということになっている))。。__(underscore*2)__(underscore*2)でで始まるメソッド・属性は始まるメソッド・属性は((建前上建前上))子クラスからアクセスで子クラスからアクセスできなくなるきなくなる(Python(Pythonのカプセル化は不十分ともいえるのカプセル化は不十分ともいえる))。。

15

OutlineOutline

1. 0. 1. 0. Object-oriented ProgrammingObject-oriented Programming- What is OOP?- What is OOP?

1. 1. 1. 1. Features of OOPFeatures of OOP- Inheritance(- Inheritance(継承継承))- Polymorphism(- Polymorphism(多態性多態性))- Dynamic binding(- Dynamic binding(動的束縛動的束縛))- Encapsulation(- Encapsulation(カプセル化カプセル化))

1. 2. Exception handling

1. 3. 1. 3. AppendixAppendix

16

Exception handling(Exception handling(例外処理例外処理))

Which do you like when you handling errors?Which do you like when you handling errors?

defdef divdiv(a, b):(a, b): ifif b == 0: b == 0: raiseraise ZeroDivisionError ZeroDivisionError elseelse:: returnreturn a / b a / bdefdef testtest(a, b):(a, b): trytry:: print div(a, b)print div(a, b) exceptexcept ZeroDivisionError: ZeroDivisionError: print "divided by zero!"print "divided by zero!"

>>> test(4, 2)>>> test(4, 2)22>>> test(4, 0)>>> test(4, 0)divided by zero!divided by zero!

defdef divdiv(a, b):(a, b): ifif b == 0: b == 0: returnreturn 0 0 elseelse:: returnreturn a / b a / bdefdef testtest(a, b):(a, b): v = div(a, b)v = div(a, b) if if v == 0 v == 0 andand a != 0: a != 0: print “divided by zero!”print “divided by zero!” elseelse:: print vprint v

>>> test(4, 2)>>> test(4, 2)22>>> test(4, 0)>>> test(4, 0)divided by zero!divided by zero!

17

Exception handling(Exception handling(例外処理例外処理))

エラー処理をどうするかエラー処理をどうするか?? 想定されうるエラーに想定されうるエラーに対して条件分岐で記述対して条件分岐で記述

特定の範囲で発生した特定の範囲で発生した例外を捕捉を捕捉

Java: catch, throwJava: catch, throwPython: except, raisePython: except, raise

エラー処理以外にも例外処エラー処理以外にも例外処理を活用すると、理を活用すると、素敵な素敵なププログラムを作成可能ログラムを作成可能((後述後述))

defdef testtest(a, b):(a, b): trytry:: print a / bprint a / b exceptexcept ZeroDivisionError: ZeroDivisionError: print "divided by zero!"print "divided by zero!" exceptexcept Exception: Exception: print "embed exception"print "embed exception" exceptexcept:: print "other exception"print "other exception" elseelse:: print "no exception"print "no exception" finallyfinally:: print "finally executed"print "finally executed">>> test(4, 2)>>> test(4, 2)22no exceptionno exceptionfinally executedfinally executed>>> test(4, 0)>>> test(4, 0)divided by zero!divided by zero!finally executedfinally executed

18

Exception handling(Exception handling(例外処理例外処理))

例外を自作することも可能例外を自作することも可能

すべての例外はクラスすべての例外はクラスBaseExceptionBaseExceptionから派生から派生

実際は、クラス実際は、クラスExceptionExceptionからの派生が推奨からの派生が推奨

instanceinstanceををraiseraiseすることすることも可能も可能

class class MyError(Exception):MyError(Exception): passpassclass class MyError2(MyError):MyError2(MyError): defdef __init____init__(self, message):(self, message): self.message = messageself.message = message defdef msgmsg():(): returnreturn self.message self.messagedefdef testtest(a):(a): trytry:: if if a == 0:a == 0: raise raise MyErrorMyError elseelse:: raise raise MyError2(“aaa”)MyError2(“aaa”) exceptexcept MyError2 MyError2 asas e: e: print e.msg()print e.msg() exceptexcept MyError: MyError: print "myerror!"print "myerror!">>> test(0)>>> test(0)>>> test(1)>>> test(1)

19

Exception handling(Exception handling(例外処理例外処理))

assertassert文文: : 主に主にdebugdebug用用偽の式が渡されると、偽の式が渡されると、AssertionErrorAssertionError例外を発生例外を発生

withwith文文: __enter__, : __enter__, __exit____exit__の呼び出しを一括の呼び出しを一括して担当。これらが定義さして担当。これらが定義されていれば、コードを簡潔れていれば、コードを簡潔に記述可能に記述可能

>>> >>> assertassert 0 == 0 0 == 0>>> >>> assertassert 0 == 1 0 == 1AssertionErrorAssertionError

# # 下記の下記の22つは等価つは等価withwith open('tmp.txt') open('tmp.txt') asas f: f: print(f.read())print(f.read())

f = open('tmp.txt').__enter__()f = open('tmp.txt').__enter__()trytry:: print(f.read())print(f.read())finallyfinally:: f.__exit__()f.__exit__()

20

OutlineOutline

1. 0. 1. 0. Object-oriented ProgrammingObject-oriented Programming- What is OOP?- What is OOP?

1. 1. 1. 1. Features of OOPFeatures of OOP- Inheritance(- Inheritance(継承継承))- Polymorphism(- Polymorphism(多態性多態性))- Dynamic binding(- Dynamic binding(動的束縛動的束縛))- Encapsulation(- Encapsulation(カプセル化カプセル化))

1. 2. 1. 2. Exception handlingException handling

1. 3. Appendix

21

Appendix: ExerciseAppendix: Exercise

課題課題: : 連結リストの実装連結リストの実装 メソッドと特殊メソッドの実装メソッドと特殊メソッドの実装

__init__, pop, append__init__, pop, appendなどから始めるのが楽などから始めるのが楽 MyLinkedListMyLinkedListををqsortqsortで整列する処理を実装で整列する処理を実装 MyLinkedListMyLinkedListを両方向リストへ拡張するを両方向リストへ拡張する

下記のコマンドでエラーが出なくなれば下記のコマンドでエラーが出なくなればOKOK

$ ipython linkedlist.py$ ipython linkedlist.py$ ipython test.py$ ipython test.py

22

Appendix: str and unicodeAppendix: str and unicode

Python2Python2の文字列についての文字列について 「普通」の文字列は「普通」の文字列はstrstr型型 u”aaa”u”aaa”という文字列はという文字列は

unicodeunicode型型 strstr型は、文字コード型は、文字コード

(encoding)(encoding)ががUTF-8UTF-8以外以外ののEUC-JPEUC-JPややShift_JISShift_JISであであることがあるることがある

strstr型への変換型への変換(encode)(encode)ややstrstr型からの変換型からの変換(decode)(decode)のときはのときはencodingencodingを指定を指定

>>> “>>> “あああ”あああ”.decode('utf-8').decode('utf-8')

>>> “>>> “あああ”あああ”.decode('euc-jp').decode('euc-jp')UnicodeDecodeErrorUnicodeDecodeError

>>> u”>>> u”あああ”あああ”.encode('utf-8').encode('utf-8')

>>> u”>>> u”あああ”あああ”.encode('euc-jp').encode('euc-jp')

>>> “>>> “あああ”あああ”.encode('utf-8').encode('utf-8')UnicodeEncodeErrorUnicodeEncodeError

>>> “>>> “あああ”あああ”.encode('euc-jp').encode('euc-jp')UnicodeEncodeErrorUnicodeEncodeError

unicode型 str型encode

decode

23

Appendix: Exception handlingAppendix: Exception handling

「素敵な」プログラムの例「素敵な」プログラムの例「文字列エンコード 「文字列エンコード « python« python練習帳」練習帳」http://php6.jp/python/2011/01/13/encoding/

defdef getEncodinggetEncoding(str):(str): forfor e e inin ['utf-8', 'shift-jis', 'euc-jp']: ['utf-8', 'shift-jis', 'euc-jp']: trytry:: str.decode(e)str.decode(e) returnreturn e e exceptexcept:: passpass returnreturn None None

>>> getEncoding(">>> getEncoding("ああああああ")")euc-jp (when src is encoded by euc-jp)euc-jp (when src is encoded by euc-jp)>>> getEncoding(u">>> getEncoding(u"ああああああ".encode('utf-8'))".encode('utf-8'))utf-8utf-8

24

Appendix: I don't like Python-san.Appendix: I don't like Python-san.

△ 文字コード周り文字コード周り((日本語処理周り日本語処理周り))が複雑が複雑 △ コーディングスタイルが束縛されるコーディングスタイルが束縛される

((機械的なルールが見やすいコードを作るとは限らない機械的なルールが見やすいコードを作るとは限らない)) △ 簡潔さを追求した結果の分かりにくい構文簡潔さを追求した結果の分かりにくい構文 △ 例外処理を「活用」した不思議なコードの存在 △ C++などのツンデレ系言語やphpのようなデレデレ系

言語との隔絶の大きさ(デレの部分がない!) △ 蛇が可愛くない蛇が可愛くない ○ 研究に必要なライブラリが充実研究に必要なライブラリが充実((自然言語処理自然言語処理etc.)etc.)

((というか、というか、PythonPython用のライブラリしかない場合が多い用のライブラリしかない場合が多い))⇨ 苦手な人は頑張りましょう苦手な人は頑張りましょう(--;(--;

­ ­ fin ­ ­(Special Thanks to Y. Takahashi)(Special Thanks to Y. Takahashi)