Latest web development tutorials

Pythonのオブジェクト指向

Pythonは最初から設計されたオブジェクト指向言語であり、そのようなものとして、Pythonでクラスとオブジェクトを作成することは非常に簡単です。 このセクションでは、我々は詳細Pythonでオブジェクト指向プログラミングをでしょう。

あなたはオブジェクト指向するプログラミング言語を暴露されていない場合は、まず、あなたがより簡単にPythonを学ぶことができますオブジェクト指向の基本概念、内部の心の中で形成されたオブジェクト指向言語の基本的な機能のいくつかを理解する必要があるかもしれませんオブジェクト指向プログラミング。

次は、オブジェクト指向のいくつかの基本的な機能の下での単純な理解をみましょう。


オブジェクト指向技術の概要

  • クラス(クラス):コレクションを記述するために使用されるオブジェクトの同じプロパティとメソッドを持っています。 これは、それぞれのオブジェクトに共通するプロパティとメソッドのセットを定義します。 オブジェクトは、クラスのインスタンスです。
  • クラス変数:クラス変数は、インスタンス化されたオブジェクト間で共通しています。 クラス変数は定義され、クラス内での関数の外側。 クラス変数は、通常、インスタンス変数として使用されていません。
  • 関連するデータ処理クラスとインスタンスオブジェクトのクラス変数やインスタンス変数:データメンバー
  • オーバーライド:あなたはサブクラスのニーズを満たすことができない場合は、親クラスのメソッドを継承し、それは、また、オーバーライドするメソッドとして知られているオーバーレイ法(オーバーライド)と呼ばれるプロセスを、書き換えることができます。
  • 変数の例:メソッドで定義された変数、現在のインスタンスのクラスの役割のみ。
  • 継承:それは派生クラス(派生クラス)が基底クラス(基底クラス)フィールドとメソッドを継承しています。 継承は、ベースクラスのオブジェクトの御馳走として、派生クラスのオブジェクトを可能にします。 例えば、このような設計がある:犬動物のクラスから派生したオブジェクトタイプ、アナログでの関係」(ある-a)は、「(図の例で、犬の動物です)。
  • クラスのインスタンスを作成し、特定のオブジェクトクラス:インスタンス化します。
  • 方法:クラス定義関数。
  • オブジェクト:クラス定義を介してデータ構造のインスタンス。 データオブジェクトは二つの部材(クラスとインスタンス変数)とメソッドが含まれます。

クラスを作成します

クラスの後、新しいクラスを作成するclassステートメントを使用し、クラス名はコロンで終わり、次の例:

class ClassName:
   '类的帮助信息'   #类文档字符串
   class_suite  #类体

ヘルプクラスは、クラス名.__ doc__内の例題で表示することができます。

class_suiteは、クラス、メソッド、データ属性のメンバーで構成します。

以下は、簡単なPythonクラスのインスタンスであります:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Employee:
   '所有员工的基类'
   empCount = 0

   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
   
   def displayCount(self):
     print "Total Employee %d" % Employee.empCount

   def displayEmployee(self):
      print "Name : ", self.name,  ", Salary: ", self.salary
  • empCount変数は、その値は、このクラスのすべてのインスタンス間で共有され、クラス変数です。 あなたはクラスや外部のクラス内Employee.empCountアクセスを使用することができます。
  • メソッドを呼び出します。このクラスのインスタンスを作成する際に最初のメソッド__init __()メソッドは、特別なメソッド、コンストラクタ、またはクラス初期化メソッドが呼び出されますされ、

オブジェクトのインスタンスを作成します。

クラスのインスタンスを作成するには、クラスの名前を使用し、__init__メソッドのパラメータを受け入れることができます。

"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)

アクセスプロパティ

あなたがオブジェクトにアクセスするには、ドット(。)プロパティを使用することができます。 次のようにクラスの名前とクラス変数へのアクセス:

emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

完全な例:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Employee:
   '所有员工的基类'
   empCount = 0

   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
   
   def displayCount(self):
     print "Total Employee %d" % Employee.empCount

   def displayEmployee(self):
      print "Name : ", self.name,  ", Salary: ", self.salary

"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

出力結果は以下の通りである上記のコードを実行します。

Name :  Zara ,Salary:  2000
Name :  Manni ,Salary:  5000
Total Employee 2

あなたは、追加、削除、次のようにクラスのプロパティを変更できます。

emp1.age = 7  # 添加一个 'age' 属性
emp1.age = 8  # 修改 'age' 属性
del emp1.age  # 删除 'age' 属性

また、プロパティは、以下の機能を使用しアクセスすることができます。

  • GETATTR(OBJ、名[、デフォルト]):プロパティアクセスオブジェクト。
  • hasattr(OBJ、名):属性があるかどうかを確認してください。
  • SETATTR(objは、名前、値):プロパティを設定します。 プロパティが存在しない場合は、新しいプロパティを作成します。
  • delattr(OBJ、名):属性を削除します。
hasattr(emp1, 'age')    # 如果存在 'age' 属性返回 True。
getattr(emp1, 'age')    # 返回 'age' 属性的值
setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8
delattr(empl, 'age')    # 删除属性 'age'

Pythonの組み込みのクラス属性

  • __dict__:(辞書を含む、データ属性クラス組成)クラスの属性
  • __doc__:文書文字列クラス
  • __name__:クラス名
  • __module__:クラス定義(フルネームは、「__クラス名を__main。 'は、クラスがインポートモジュールMYMODに配置されている場合は、classNameの.__ module__等しくMYMOD)モジュール
  • __bases__:(すべてのタプルからなる親クラスを含んで)親要素のすべてのクラス

Pythonは呼び出しビルトインクラス属性の例は以下のとおりです。

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Employee:
   '所有员工的基类'
   empCount = 0

   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
   
   def displayCount(self):
     print "Total Employee %d" % Employee.empCount

   def displayEmployee(self):
      print "Name : ", self.name,  ", Salary: ", self.salary

print "Employee.__doc__:", Employee.__doc__
print "Employee.__name__:", Employee.__name__
print "Employee.__module__:", Employee.__module__
print "Employee.__bases__:", Employee.__bases__
print "Employee.__dict__:", Employee.__dict__

出力結果は以下の通りである上記のコードを実行します。

Employee.__doc__: 所有员工的基类
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}

Pythonのオブジェクトが破壊される(ガベージコレクション)

Java言語と同様に、Pythonは参照メモリ内のオブジェクトを追跡するために、この単純な技術をカウントを使用しています。

参考文献のそれぞれの数を使用しているすべてのオブジェクトのPythonの内部レコードで。

内部トラッキング変数は、参照カウンタと呼ばれます。

オブジェクトが作成されると、それがガベージコレクションで、オブジェクトが不要になった場合、それはオブジェクト数への参照が0になる、と言うことではない、参照カウントを生成します。 回復は適切な時にインタプリタによって「すぐに」ではありません。しかし、ガベージオブジェクトがメモリ空間の再利用を占めます。

a = 40      # 创建对象  <40>
b = a       # 增加引用, <40> 的计数
c = [b]     # 增加引用.  <40> 的计数

del a       # 减少引用 <40> 的计数
b = 100     # 减少引用 <40> 的计数
c[0] = -1   # 减少引用 <40> 的计数

オブジェクトの参照カウントのためだけでなく、ガベージコレクションのメカニズムは同じでも、循環参照のケースを扱うことができ、0です。 これは、2つのオブジェクトが相互に参照し、循環参照を意味しませんが、他の変数の参照それら。 この場合、唯一の参照カウントは十分ではありません。 Pythonのガベージコレクタは、実際にはサイクルカウンタと、ガベージコレクタへの参照です。 補足参照カウントのガベージコレクタは、合計金額に注意を支払うことになりますように大きなオブジェクトを割り当てられた(参照によって破壊されたものはカウントされません)。 この場合、インタプリタはすべて参照されていないサイクルをクリーンアップしようとすると、一時停止します。

デストラクタ__del__、__ del__は、オブジェクトはもはや実行するには、__ del__メソッドを使用している場合、オブジェクトが破棄されたときに呼び出されません。

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Point:
   def __init__( self, x=0, y=0):
      self.x = x
      self.y = y
   def __del__(self):
      class_name = self.__class__.__name__
      print class_name, "销毁"

pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # 打印对象的id
del pt1
del pt2
del pt3

次のように上記の結果の例を次に示します。

3083401324 3083401324 3083401324
Point 销毁

注:通常は、別のファイルにクラスを定義する必要があり、

クラス継承

オブジェクト指向プログラミングの主な利点の1つは、これらのいずれかが継承メカニズムを介して行われ達成するために、コードの再利用を再利用するためにもたらされます。 クラス間の完全に理解しやすいタイプとサブタイプ関係を継承。

警告: 継承構文クラスの派生クラス名(基底クラス名):// ...括弧内の基底クラス名を書いて、基底クラスが指定されたタプルの中で、クラス定義です。

機能のいくつかのパイソン続いて:

  • 1:以下の構成(__init __()メソッド)でチェンZhongjiクラスが自動的に起動されることはありません、それは個人的にその派生クラスのコンストラクタで呼ばれる特殊が必要です。
  • 2:あなたは、基本クラスのメソッドを呼び出すと、あなたは、基本クラスのクラス名のプレフィックス、および自己パラメータ変数を持参する必要性を追加する必要があります。 自己パラメータを持参する必要はありません、クラスの通常の関数呼び出しとは異なります
  • 3:それは派生クラス内の対応するメソッドを見つけることができない場合はPythonは常に最初に、アプローチの対応するタイプを見つけ、それが基底クラスに1つずつ見て始めました。 (第一の方法は、基本クラスを見つけるために見つけるために、このクラスで見つけるために呼び出します)。

列継承タプルの複数のクラスならば、それは「多重継承」と呼ばれています。

構文:

次のように派生クラスの宣言は、その親クラスと同様に、その後、クラス名を持つ基本クラスのリストを継承します。

class SubClassName (ParentClass1[, ParentClass2, ...]):
   'Optional class documentation string'
   class_suite

例:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Parent:        # 定义父类
   parentAttr = 100
   def __init__(self):
      print "调用父类构造函数"

   def parentMethod(self):
      print '调用父类方法'

   def setAttr(self, attr):
      Parent.parentAttr = attr

   def getAttr(self):
      print "父类属性 :", Parent.parentAttr

class Child(Parent): # 定义子类
   def __init__(self):
      print "调用子类构造方法"

   def childMethod(self):
      print '调用子类方法 child method'

c = Child()          # 实例化子类
c.childMethod()      # 调用子类的方法
c.parentMethod()     # 调用父类方法
c.setAttr(200)       # 再次调用父类的方法
c.getAttr()          # 再次调用父类的方法

次のように上記のコードが実行されます。

调用子类构造方法
调用子类方法 child method
调用父类方法
父类属性 : 200

あなたは複数のクラスを継承することができます

class A:        # 定义类 A
.....

class B:         # 定义类 B
.....

class C(A, B):   # 继承类 A 和 B
.....

あなたが検出するために、issubclass()またはでisinstance()メソッドを使用することができます。

  • issubclass(サブ、SUP):クラスが別のクラスまたは派生クラスの構文のサブクラスであるかどうかを判断するブール関数 - issubclass()
  • でisinstance(objは、クラス)ブール関数objはオブジェクトクラスまたはインスタンスオブジェクトクラスのクラスのインスタンスである場合は、サブクラスがtrueを返すです。

メソッドのオーバーライド

あなたは親クラスのメソッドである関数はあなたのニーズを満たすことができない場合は、サブクラスで、あなたの親クラスのメソッドを書き換えることができます。

例:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Parent:        # 定义父类
   def myMethod(self):
      print '调用父类方法'

class Child(Parent): # 定义子类
   def myMethod(self):
      print '调用子类方法'

c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法

出力結果は以下の通りである上記のコードを実行します。

调用子类方法

財団オーバーロードされたメソッド

次の表は、あなたのクラスでオーバーライドすることができ、共通の機能の一部を示しています。

いいえ。 単に呼び出す&を説明した方法、
1 __init__(自己[、引数...] )
単にコンストラクタメソッドを呼び出します。OBJ =クラス名(引数)
2 __del __(自己)
デルOBJ:デストラクタ、オブジェクトの単純なメソッド呼び出しを削除
3 __repr __(自己)
repr(obj)は単純なメソッド呼び出しを読み取るための通訳のための形式の変換
4 __str __(自己)
STR(obj)は単純なメソッド呼び出しを読んで、人間に適した形に値のために
5 __cmp__(自己、x)は、
CMP(OBJ、x)は比較的単純なメソッド呼び出しオブジェクト

演算子の多重定義

Pythonはまた、次のような例は、演算子のオーバーロードをサポートしています。

#!/usr/bin/python

class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b

   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)
   
   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2

次のように上記のコードの実行結果は以下のとおりです。

Vector(7,8)

クラスの属性とメソッド

プライベートプロパティクラス

__private_attrs:プロパティがプライベートで使用するか、または外部クラスに直接アクセスできないことを示す2つのアンダースコアを開始します。 自己.__ private_attrsクラスメソッド内で使用されるとき。

クラスメソッド

地上波内部には、使用defキーワードは、異なる機能の一般的な定義とクラスメソッドとして定義することができ、クラスメソッドは、パラメータ、自己が含まれ、最初のパラメータとして必要があります

クラスのプライベートメソッド

__private_method:最初の2アンダースコア、メソッドは、クラスのprivateメソッドは外部から呼び出すことができないと宣言されています。 クラス内で自己.__ private_methodsを呼び出し

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class JustCounter:
	__secretCount = 0  # 私有变量
	publicCount = 0    # 公开变量

	def count(self):
		self.__secretCount += 1
		self.publicCount += 1
		print self.__secretCount

counter = JustCounter()
counter.count()
counter.count()
print counter.publicCount
print counter.__secretCount  # 报错,实例不能访问私有变量

クラスの名前が含まれるように名前を変更することでPythonの:

1
2
2
Traceback (most recent call last):
  File "test.py", line 17, in <module>
    print counter.__secretCount  # 报错,实例不能访问私有变量
AttributeError: JustCounter instance has no attribute '__secretCount'

Pythonはインスタンス化されたクラスのアクセスプライベートデータを許可されていませんが、あなたはobject._className__attrNameアクセス属性を使用することができ、次のコードは、コード上記のコードの最後の行を置き換えます:

.........................
print counter._JustCounter__secretCount

次のように上記のコードを実行し、実行結果は以下のとおりです。

1
2
2
2