Ad
2: 2017-01-07 (土) 07:35:56 njf ソース バックアップ No.2 を復元して編集 現: 2017-01-10 (火) 19:28:19 njf ソース 編集
Line 8: Line 8:
クラスの定義は「class」で行います。 クラスの定義は「class」で行います。
 +クラス名の後には「(obect)」を付けます。
 +これは省略可能ですが、継承などで一部の記法が使えなくなるので付けるようにするのがオススメです。
メソッドの定義は「def」です。 メソッドの定義は「def」です。
コンストラクタは「__init__」で、インスタンス化に「new」は不要です。 コンストラクタは「__init__」で、インスタンス化に「new」は不要です。
- class TestClass:+ class TestClass(object):
     def __init__(self):      def __init__(self):
         print "construct!"          print "construct!"
 + 
 testClass = TestClass()  testClass = TestClass()
Line 23: Line 25:
他の言語で言うところの「this」とほぼ同じです。 他の言語で言うところの「this」とほぼ同じです。
- class TestClass: + 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()
結果 結果
- <type 'instance'> + <class '__main__.TestClass'> 
- <__main__.TestClass instance at 0x10c2a4bd8>+ <__main__.TestClass object at 0x10bcdb8d0> 
この「self」を使ってクラス内のメソッドを呼びます。 この「self」を使ってクラス内のメソッドを呼びます。
多くの他言語の「this」と違って、省略することはできません。 多くの他言語の「this」と違って、省略することはできません。
- class CallMethod:+ class CallMethod(obect):
     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()
Line 57: Line 60:
クラス変数はクラス名でも「self」を含むインスタンスからでも参照可能です。 クラス変数はクラス名でも「self」を含むインスタンスからでも参照可能です。
- class ClassVariables:+ class ClassVariables(obect):
     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 
 + 
 classVariables = ClassVariables()  classVariables = ClassVariables()
 + 
 print ClassVariables.a  print ClassVariables.a
 print classVariables.a  print classVariables.a
 + print classVariables.c
結果 結果
 2  2
 1  1
 10  10
 + 11
-ここでインスタンスでそのクラス変数を参照するときには、もしインスタンスでその変数を変更していなければ初期値を参照し、そうでなければ変更後の値を参照します。+ここでインスタンスでそのクラス変数を参照するときには、もしインスタンスでその変数を変更していなければ初期値を参照し、そうでなければ変更後の値を参照します。また、インスタンスの変数はメソッドの中で始めて定義することもできます。 
 + 
 +言い換えれば、インスタンスの変数はメソッドで代入したときに始めて定義され、その後はクラス変数よりインスタンスの変数を優先して参照すると言うことです。
これは他のprototype型のクラス定義を採用している言語と同様です。 これは他のprototype型のクラス定義を採用している言語と同様です。
Line 82: Line 89:
Pythonではprivateなどの参照範囲を制限する修飾子はサポートされていません。 Pythonではprivateなどの参照範囲を制限する修飾子はサポートされていません。
-代わりに「_」(アンダーバー)で始まる要素には慣習的にクラス外から参照しない(しようと思えばできる)、「__」(アンダーバー2つ)で始まる要素はクラス外から参照するとエラーになる、という命名ルールがあります。 +代わりに「_」(アンダーバー)で始まる要素には慣習的にクラス外から参照しない(しようと思えばできる)、「__」(アンダーバー2つ)で始まる要素はクラス外から参照するとエラーになる(しかし、こちらもしようど思えばできる)、という命名ルールがあります。 
- class PrivateMethod:+ 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()
-「_」で始まるメソッドは参照可能(ただし非推奨)。+「_」で始まるメソッドは参照可能(ただし慣習的に参照するのは非推奨)。
 privateMethod._method()  privateMethod._method()
結果 結果
 __method  __method
-「__」で始まるメソッドはクラス内からの呼び出しは可能ですが、外部から呼び出すとエラー。+「__」で始まるメソッドはクラス内からの呼び出しは可能ですが、外部から呼び出すとエラーとなります。
 privateMethod.__method()  privateMethod.__method()
Line 106: Line 113:
 AttributeError: PrivateMethod instance has no attribute '__method'  AttributeError: PrivateMethod instance has no attribute '__method'
-&font(Red){制作中};+しかし、実はこれは「__」で始まるメソッドは「_クラス名メソッド名」と名前が変更されるだけなので、無理矢理アクセスすることも可能です。 
 + 
 +&nbsp;privateMethod._PrivateMethod__method() 
 + 
 +結果 
 + 
 + ;__privateMethod 
 + 
 +つまり、Pythonには言語仕様として完全にアクセス範囲を制限する機能はありません。 
 +そのため、アクセスをコントロールするには人間が気をつけるしかありません。 
 +プログラムを無駄に複雑にしないために、なるべく慣習的なスタイルを守るようにしましょう。
*継承 [#u224ed0a] *継承 [#u224ed0a]
 +
 +継承はクラス名の後の「()」の中に親クラスの名前を入れることで行います。
 +親クラスへのアクセスはそのままクラス名を指定するか、「super」関数を使います。
 +
 + class ParentClass(object):
 +     def __init__(self):
 +         print "parent"
 + 
 +     def printType(self):
 +         print type(self)
 + 
 + 
 + class ChildClass(ParentClass):
 + 
 +     def __init__(self):
 +         ParentClass.__init__(self)
 + 
 +     def printType(self):
 +         super(ChildClass,self).printType()
 + 
 + childClass = ChildClass()
 + childClass.printType()
 +
 +結果
 + parent
 + <class '__main__.ChildClass'>
 +
 +「super」は親クラスの名前を知らなくても利用できるので、コピペしたときに親を参照したいのに別クラスを参照してしまったというような事故なども防げて何かと便利です。
 +しかし、クラスの定義のところで、「(object)」を付けた方が良いと書きましたが、もしこれを省略すると「super」が使えなくなります。
 +
 +つまり「(object)」を指定することで、Pythonのobject型を継承していると判断され、それ特有の関数なども使えるようになるわけです。
 +
 +Pythonでは全ての基本的なクラスは「object」を継承しているので、それにならってクラスを自作するときも「object」を継承しておくのがおすすめです。
 +
 +ただし、小規模な開発でのクラス定義だと、さほどobjectを継承させるメリットは無いかも知れないので、場合によって調整してください。
 +
 +また、Pythonは多重継承もサポートしています
 +
 + class Class1(Class2,Class3):
 + ...
 +
 +ただし、多重継承は継承関係が複雑化したり名前の衝突が起きやすいことから嫌われる傾向にあります。メリットがはっきりしている場合を除けば避けた方が無難かも知れません。
 +
*クラスメソッドとスタティックメソッド [#o110c130] *クラスメソッドとスタティックメソッド [#o110c130]
 +
 +Pythonではクラスメソッドとスタティックメソッドの両方が使えます。
 +
 +記法としては「@classmethod」と「@staticmethod」というアノテーションを使います。
 +
 +
 + class StaticAndClassMethod(object):
 +     @classmethod
 +     def classMethod(cls):
 +         print "class method"
 + 
 +     @staticmethod
 +     def staticMethod():
 +         print "static method"
 + 
 + 
 + StaticAndClassMethod.classMethod()
 + StaticAndClassMethod.staticMethod()
 +
 +結果
 + class method
 + static method
 +
 +クラスメソッドとスタティックメソッドの違いは、第一引数にクラスをとるかどうかです。
 +
 +そのため、メソッドの中でクラスを使わないならスタティックメソッドを使うのが普通です。
 +
 +しかし、クラス名を使えばスタティックメソッドから他のスタティックメソッドにアクセスできますし、クラスメソッドでクラスを使わないことも可能なので、明確に違いがあるというわけでもありません。実際、どちらかのみを実装しているPython以外の言語も多くあります。
 +
 +使いどころとしては、似たような関数がたくさんある場合には、それを一つのクラスのメソッドにすると名前の衝突が起こりにくく、また同様の関数がまとまってわかりやすくなります。また、作ったクラスに関連した関数がある場合にはまとめると関連がわかりやすくなります。
 +
 +しかし小規模開発なら関数の個数自体が少ないので、スタティックメソッドは使わず関数のみを使用しても十分でしょう。


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード印刷に適した表示   ページ新規作成 全ページ一覧 単語検索 最新ページの一覧   ヘルプ   最新ページのRSS 1.0 最新ページのRSS 2.0 最新ページのRSS Atom Powered by xpWiki
Counter: 2376, today: 1, yesterday: 1
MenuBar
広告

ログイン

ユーザー名:


パスワード:





パスワード紛失

Portuguese | English | German | Greek | Japanese | Korean | Russian | T-Chinese top
NJF