Python オブジェクト指向

高洛峰
高洛峰オリジナル
2016-11-23 14:09:081000ブラウズ

Python は最初からオブジェクト指向言語であり、そのため Python でクラスやオブジェクトを作成するのは簡単です。この章では、Python によるオブジェクト指向プログラミングについて詳しく紹介します。

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

次に、オブジェクト指向の基本的な特徴をいくつか簡単に理解しましょう。

オブジェクト指向テクノロジーの概要

クラス (クラス): 同じプロパティとメソッドを持つオブジェクトのコレクションを記述するために使用されます。コレクション内のすべてのオブジェクトに共通のプロパティとメソッドを定義します。オブジェクトはクラスのインスタンスです。

クラス変数: クラス変数は、インスタンス化されたオブジェクト全体でパブリックです。クラス変数は、クラス内および関数本体の外で定義されます。クラス変数は通常、インスタンス変数としては使用されません。

データ メンバー: クラス変数またはインスタンス変数は、クラスとそのインスタンス オブジェクトに関連するデータを処理するために使用されます。

メソッドのオーバーロード: 親クラスから継承されたメソッドがサブクラスのニーズを満たせない場合、このプロセスはメソッド オーバーライドと呼ばれ、メソッドのオーバーロードとも呼ばれます。

インスタンス変数: メソッドで定義された変数は、現在のインスタンスのクラスにのみ作用します。

継承: つまり、派生クラスは基本クラスのフィールドとメソッドを継承します。継承により、派生クラスのオブジェクトを基本クラス オブジェクトとして扱うこともできます。たとえば、次のような設計があります。Dog タイプのオブジェクトは、「is-a」関係 (たとえば、Dog is an Animal) をシミュレートする Animal クラスから派生します。

インスタンス化: クラスのインスタンス、クラスの特定のオブジェクトを作成します。

メソッド: クラスで定義された関数。

オブジェクト: クラスを通じて定義されたデータ構造のインスタンス。オブジェクトには 2 つのデータ メンバー (クラス変数とインスタンス変数) とメソッドが含まれます。

クラスを作成します

次の例のように、class ステートメントを使用して新しいクラスを作成し、クラスの名前を指定し、コロンで終わります。 class document string'#クラスドキュメント文字列

class_suite #クラス本体

クラスのヘルプ情報は、ClassName.__doc__ を通じて参照できます。

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

以下は簡単な Python クラスの例です:

class Employee:

'全従業員の共通基本クラス'

empCount = 0

def __init__(self, name,給与):

self.name self.name %d" % Employee.empCount

def displayEmployee(self):

print "名前: ", self.name, ", 給与: ", self.salary

empCount 変数はクラス変数であり、その値はインスタンス間で共有されるこのクラスすべてに含まれます。内部クラスまたは外部クラスで Employee.empCount を使用してアクセスできます。

最初のメソッド __init__() メソッドは、クラスのコンストラクターまたは初期化メソッドと呼ばれる特別なメソッドです。このメソッドは、このクラスのインスタンスが作成されるときに呼び出されます

インスタンス オブジェクトを作成する

インスタンスを作成するにはクラスの場合は、クラスの名前を使用し、 __init__ メソッドを通じて引数を受け取ります。

"これにより、Employee クラスの最初のオブジェクトが作成されます"

emp1 = Employee("Zara", 2000)

"これにより、Employee クラスの 2 番目のオブジェクトが作成されます"

emp2 = Employee("Manni", 5000)

プロパティへのアクセス

ドット (.) を使用して、オブジェクトのプロパティにアクセスできます。次のクラス名を使用してクラス変数にアクセスします:

emp1.displayEmployee()

emp2.​​displayEmployee()

print "Total Employee %d" % Employee.empCount

完全な例:

#!/usr/bin/python

class Employee:

'全従業員の共通基本クラス'

empCount = 0

def __init__(self, name,給与):

M Self.Name = 名前

self.salary = 給与

従業員.empcount+= 1

defiddlayCount (SELF):

O Print "従業員合計 %D" %Employee.empCount

def displayemployee (Self):

Print "name:", seld.name, ", Self.salary

Employee クラスの最初のオブジェクトを作成します"

emp1 = Employee("Zara", 2000)

"これにより、Employee クラスの 2 番目のオブジェクトが作成されます"

emp2 = Employee("Manni", 5000 )

emp1.displayEmployee()

emp2.​​displayEmployee()

print "Total Employee %d" % Employee.empCount

上記のコードを実行すると、出力結果は次のようになります:

名前 : Zara 、給与: 2000

名前 : Manni 、給与: 5000

従業員総数 2

以下に示すように、クラスの属性を追加、削除、変更できます:

emp1.age = 7 # 「年齢」属性を追加します

emp1.age = 8 # 「年齢」属性を変更します

del emp1.age # 「年齢」属性を削除します

次の関数を使用して属性にアクセスします:

getattr(obj, name[,default]): オブジェクトのプロパティにアクセスします。

hasattr(obj,name) : 属性が存在するかどうかを確認します。

setattr(obj,name,value): 属性を設定します。プロパティが存在しない場合は、新しいプロパティが作成されます。

delattr(obj, name) : 属性を削除します。

hasattr(emp1, 'age') # 'age' 属性が存在する場合は True を返します。

getattr(emp1, 'age') # 'age' 属性の値を返す

setattr(emp1, 'age', 8) # 値 8 を持つ属性 'age' を追加する

delattr(empl, 'age') # 属性 'age' を削除します

Python 組み込みクラス属性

__dict__: クラスの属性 (クラスのデータ属性で構成される辞書が含まれます)

__doc__: ドキュメント文字列クラスの

__name__: クラス名

__module__: クラスが定義されているモジュール (クラスの完全名は '__main__.className' です。クラスがインポートされたモジュール mymod にある場合、className.__module__ mymod と等しい)

__bases__: クラスのすべての親クラス要素 (すべての親クラスで構成されるタプルを含む)

Python 組み込みクラス属性の呼び出し例は次のとおりです:

#!/ usr/bin/python

class Employee:

'全従業員の共通基本クラス'

empCount = 0

def __init__(self, name,給与):

self.name = name

self.salary =給与

Employee.empCount += 1

def displayCount( self):

print "従業員合計 %d" % Employee.empCount

def displayEmployee(self):

print "名前: ", self.name, ", 給与: ", 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.__module__: __main__

Employee.__bases__: ()

Employee.__dict__: {'__module__' : '__main__', 'displayCount':

, 'empCount': 2,

'displayEmployee': ,

'__doc__': '共通基本クラスall従業員',

🎜'__init__': }🎜🎜 🎜🎜 🎜🎜python オブジェクトの破棄 (ガベージ コレクション)🎜🎜 Java 言語と同様に、Python は参照カウントと呼ばれる単純なテクノロジを使用してオブジェクトを追跡しますメモリ。 🎜🎜Python は内部的に、使用中の各オブジェクトが持つ参照の数を記録します。 🎜🎜リファレンスカウンターと呼ばれる内部追跡変数。 🎜

オブジェクトが作成されると、参照カウントが作成され、そのオブジェクトが不要になると、つまりオブジェクトの参照カウントが 0 になると、ガベージ コレクションされます。ただし、リサイクルは「即時」ではありません。インタプリタは、ガベージ オブジェクトによって占有されているメモリ領域を適切なタイミングでリサイクルします。

a = 40 # オブジェクトを作成します <40>

b = a # の数を増やします

c = [b] #

の数を追加します。

del a # 参照数を減らす

b = 100 # 参照数を減らす

c[0] = -1 # 参照数を減らす

ガベージ コレクション メカニズムは、参照カウントが 0 のオブジェクトを対象とするだけでなく、循環参照も処理できます。循環参照は、2 つのオブジェクトが相互に参照しているが、他の変数がそれらを参照していない場合に発生します。この場合、参照カウントだけでは十分ではありません。 Python のガベージ コレクターは、実際には参照カウンターと循環ガベージ コレクターです。参照カウントに加えて、ガベージ コレクターは、大量に割り当てられたオブジェクト (および参照カウントによって破棄されていないオブジェクト) も調べます。 この場合、インタプリタは一時停止し、参照されていないループをクリーンアップしようとします。

Instance

Destructor __del__、__del__ は、オブジェクトが使用されなくなったときに呼び出されます。

#!/usr/bin/python

class ポイント:

def __init(self, x=0, y=0):

self.x = x

self.y = y

def __del__(self):

class_name = self.__class__ .__name__

print class_name, "destroyed"

pt1 = Point()

pt2 = pt1

pt3 = pt1

print id(pt1), id(pt2), id(pt3) # オブジェクトidを印刷します

del pt1

del pt2

del pt3

上記の例の実行結果は次のとおりです:

3083401324 30834 01324

ポイントが破壊されました

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

クラスの継承

オブジェクト指向プログラミングの主な利点の 1 つは、コードの再利用、この再利用を実現するためのメソッドです。継承メカニズムを通じて。継承は、クラス間のタイプとサブタイプの関係として完全に理解できます。

注意事項: 継承構文 class 派生クラス名 (基底クラス名): //... 基底クラス名は括弧内に記述されます。基底クラスはクラス定義時にタプルに指定されます。

Python の継承のいくつかの機能:

1: 継承では、基本クラスの構築 (__init__() メソッド) は自動的に呼び出されず、その派生クラスの構築で具体的に呼び出す必要があります。

2: 基本クラスのメソッドを呼び出すときは、基本クラスのクラス名のプレフィックスを追加し、self パラメーター変数を渡す必要があります。クラス内で通常の関数を呼び出すのとは異なり、self パラメータを持ってくる必要はありません

3: Python は常に最初に対応する型のメソッドを検索し、派生クラスで対応するメソッドが見つからない場合、処理を開始します。基本クラスを 1 つずつ検索します。 (最初にこのクラスで呼び出しメソッドを探し、見つからない場合は基本クラスで探します)。

継承タプルに複数のクラスがリストされている場合、それは「多重継承」と呼ばれます。

構文:

次のように、クラス名の後に継承された基本クラスのリストを伴う、親クラスと同様の派生クラスの宣言:

class SubClassName (ParentClass1[, ParentClass2, ... : # 親クラスを定義します

parentAttr = 100e DEF __init __ (Self):

Print "Calling Parent Constructor"

DEF PARENTMETHOD (Self):

Print 'Calling Parent Method'

DE Fセルフ、属性):

Parent.parentAttr = attr

def getAttr(self):

print "親属性:", Parent.parentAttr

class Child(Parent): #def __init__(self):

print "子コンストラクターの呼び出し"

def childMethod(self):

print '子メソッドの呼び出し'

c =Child() Tc.getattr ()# 親クラスを再度呼び出すメソッド

上記コードの実行結果は以下の通りです。

子の呼び出しコンストラクター

子メソッドの呼び出し

親メソッドの呼び出し 属性: 200

複数のクラスを継承できます

class A: # クラス A を定義します

....

クラス B : # クラス B を定義します

... ..

class C(A, B): # A と B のサブクラス

....

issubclass() を使用できます。または isinstance() メソッドで検出します。

issubclass() - クラスがサブクラスであるか、別のクラスの子孫であるかを判断するブール関数、構文: issubclass(sub,sup)

isinstance(obj, Class) obj が Class クラスのインスタンス オブジェクトの場合のブール関数または Class サブクラスのインスタンス オブジェクトは true を返します。

メソッドのオーバーロード

親クラスのメソッドの関数がニーズを満たせない場合は、サブクラスで親クラスのメソッドをオーバーロードできます:

Instance:

#!/usr/bin /python

classParent: def myMethod(self) ; 上記のコードを実行した出力結果は次のとおりです。表には、独自のクラスでオーバーライドできるいくつかの一般的な関数がリストされています:

シリアル番号

メソッド、説明、単純な呼び出し

1 __init__ ( self [,args...] )

コンストラクター

単純な呼び出しメソッド: obj = className(args)

2 __del__( self )

デストラクター メソッド、オブジェクトを削除します

単純な呼び出しメソッド: dell obj

3 __repr__( self )

はインタープリターが読み取るための形式に変換されます

単純な呼び出しメソッド: repr(obj)

4 __str__( self )

は、値を人間が読める形式に適した形式に変換するために使用されます

単純な呼び出しメソッド: str(obj)

5 __cmp__ (self, x)

Object比較

単純な呼び出しメソッド: cmp(obj, x)

演算子のオーバーロード

Python は演算子のオーバーロードもサポートしています。例は次のとおりです。 :

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)



データを非表示にする

Python でデータ非表示を実装するのは非常に簡単です。クラス変数名またはメンバー関数の前に 2 つのアンダースコアを追加する限り、前にキーワードを追加する必要はありません。これにより、クラスのインスタンスに対してはその変数名とメンバ関数が使用できなくなり、そのクラスの継承クラスに対してもデータを非表示にすることができます。名前の競合を引き起こさずに、正確な変数名またはメンバー関数名を定義します。 例:

#!/usr/bin/python

class JustCounter:

__secretCount = 0

def count(self):

self.__secretCount += 1

print self.__secretCount

カウンター= JustCounter()

counter.count()

counter.count()

print counter.__secretCount

Python はクラス名を含むように名前を変更します:

1

2

トレースバック (最後の呼び出し):

ファイル "test.py"、12 行目、

print counter.__secretCount

AttributeError: JustCounter インスタンスには属性 '__secretCount' がありません

Python では、インスタンス化されたクラスが非表示データにアクセスすることはできませんが、object._className__attrName を使用して属性にアクセスできます。上記のコードの最後の行を次のコードに置き換えます:

.... .. ......

print counter._JustCounter__secretCount

上記のコードを実行すると、実行結果は次のようになります:

1

2

2


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:Python の正規表現次の記事:Python の正規表現