3: 2017-01-10 (火) 10:56:22 njf |
現: 2017-01-10 (火) 20:28:19 njf |
| クラスの定義は「class」で行います。 | | クラスの定義は「class」で行います。 |
| クラス名の後には「(obect)」を付けます。 | | クラス名の後には「(obect)」を付けます。 |
- | 古いPythonではこれは必要なく、今でも省略可能ですが、継承などで一部の記法が使えなくなるので付けるようにするのがオススメです。 | + | これは省略可能ですが、継承などで一部の記法が使えなくなるので付けるようにするのがオススメです。 |
| メソッドの定義は「def」です。 | | メソッドの定義は「def」です。 |
| コンストラクタは「__init__」で、インスタンス化に「new」は不要です。 | | コンストラクタは「__init__」で、インスタンス化に「new」は不要です。 |
| def __init__(self): | | def __init__(self): |
| print "construct!" | | print "construct!" |
| + | |
| testClass = TestClass() | | testClass = TestClass() |
| | | |
| | | |
| class TestClass(obect): | | class TestClass(obect): |
| + | |
| def whatIsSelf(self): | | def whatIsSelf(self): |
| print type(self) | | print type(self) |
| print self | | print self |
| + | |
| testClass = TestClass() | | testClass = TestClass() |
| + | |
| testClass.whatIsSelf() | | testClass.whatIsSelf() |
| | | |
| def method1(self): | | def method1(self): |
| print "method1 called" | | print "method1 called" |
| + | |
| def method2(self): | | def method2(self): |
| self.method1() | | self.method1() |
| + | |
| callMethod = CallMethod() | | callMethod = CallMethod() |
| + | |
| callMethod.method2() | | callMethod.method2() |
| | | |
| a = 1 | | a = 1 |
| b = 2 | | b = 2 |
| + | |
| def __init__(self): | | def __init__(self): |
| print self.b | | print self.b |
| self.a = 10 | | self.a = 10 |
| self.c = 11 | | self.c = 11 |
| + | |
| classVariables = ClassVariables() | | classVariables = ClassVariables() |
| + | |
| print ClassVariables.a | | print ClassVariables.a |
| print classVariables.a | | print classVariables.a |
| | | |
| Pythonではprivateなどの参照範囲を制限する修飾子はサポートされていません。 | | Pythonではprivateなどの参照範囲を制限する修飾子はサポートされていません。 |
- | 代わりに「_」(アンダーバー)で始まる要素には慣習的にクラス外から参照しない(しようと思えばできる)、「__」(アンダーバー2つ)で始まる要素はクラス外から参照するとエラーになる、という命名ルールがあります。 | + | 代わりに「_」(アンダーバー)で始まる要素には慣習的にクラス外から参照しない(しようと思えばできる)、「__」(アンダーバー2つ)で始まる要素はクラス外から参照するとエラーになる(しかし、こちらもしようど思えばできる)、という命名ルールがあります。 |
| class PrivateMethod(object): | | class PrivateMethod(object): |
| def __method(self): | | def __method(self): |
| print "__method" | | print "__method" |
| + | |
| def _method(self): | | def _method(self): |
| self.__method() | | self.__method() |
| + | |
| privateMethod = PrivateMethod() | | privateMethod = PrivateMethod() |
| | | |
| AttributeError: PrivateMethod instance has no attribute '__method' | | AttributeError: PrivateMethod instance has no attribute '__method' |
| | | |
- | しかし、実はこれは「__」で始まるメソッドは「_クラス名メソッド名」と名前が変更されるだけなので、実は無理矢理アクセスすることも可能です。 | + | しかし、実はこれは「__」で始まるメソッドは「_クラス名メソッド名」と名前が変更されるだけなので、無理矢理アクセスすることも可能です。 |
| | | |
- | privateMethod = privateMethod._PrivateMethod__method() | + | privateMethod._PrivateMethod__method() |
| | | |
| 結果 | | 結果 |
| | | |
| つまり、Pythonには言語仕様として完全にアクセス範囲を制限する機能はありません。 | | つまり、Pythonには言語仕様として完全にアクセス範囲を制限する機能はありません。 |
- | そのため、プログラムを無駄に複雑にしないために、なるべく慣習的なスタイルを守るようにしましょう。 | + | そのため、アクセスをコントロールするには人間が気をつけるしかありません。 |
| + | プログラムを無駄に複雑にしないために、なるべく慣習的なスタイルを守るようにしましょう。 |
| | | |
| *継承 [#u224ed0a] | | *継承 [#u224ed0a] |
| def __init__(self): | | def __init__(self): |
| print "parent" | | print "parent" |
| + | |
| def printType(self): | | def printType(self): |
| print type(self) | | print type(self) |
- | | + | |
| + | |
| class ChildClass(ParentClass): | | class ChildClass(ParentClass): |
| + | |
| def __init__(self): | | def __init__(self): |
| ParentClass.__init__(self) | | ParentClass.__init__(self) |
| + | |
| def printType(self): | | def printType(self): |
| super(ChildClass,self).printType() | | super(ChildClass,self).printType() |
| + | |
| childClass = ChildClass() | | childClass = ChildClass() |
| childClass.printType() | | childClass.printType() |
| def classMethod(cls): | | def classMethod(cls): |
| print "class method" | | print "class method" |
| + | |
| @staticmethod | | @staticmethod |
| def staticMethod(): | | def staticMethod(): |
| print "static method" | | print "static method" |
- | | + | |
| + | |
| StaticAndClassMethod.classMethod() | | StaticAndClassMethod.classMethod() |
| StaticAndClassMethod.staticMethod() | | StaticAndClassMethod.staticMethod() |
| + | |
| + | 結果 |
| + | class method |
| + | static method |
| + | |
| + | クラスメソッドとスタティックメソッドの違いは、第一引数にクラスをとるかどうかです。 |
| + | |
| + | そのため、メソッドの中でクラスを使わないならスタティックメソッドを使うのが普通です。 |
| + | |
| + | しかし、クラス名を使えばスタティックメソッドから他のスタティックメソッドにアクセスできますし、クラスメソッドでクラスを使わないことも可能なので、明確に違いがあるというわけでもありません。実際、どちらかのみを実装しているPython以外の言語も多くあります。 |
| + | |
| + | 使いどころとしては、似たような関数がたくさんある場合には、それを一つのクラスのメソッドにすると名前の衝突が起こりにくく、また同様の関数がまとまってわかりやすくなります。また、作ったクラスに関連した関数がある場合にはまとめると関連がわかりやすくなります。 |
| + | |
| + | しかし小規模開発なら関数の個数自体が少ないので、スタティックメソッドは使わず関数のみを使用しても十分でしょう。 |