工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> Python

Python-オブジェクト指向

前のページ次のページ

Python は、その存在以来、オブジェクト指向言語でした。このため、クラスとオブジェクトの作成と使用は非常に簡単です。この章は、Python のオブジェクト指向プログラミング サポートを使用するエキスパートになるのに役立ちます。

オブジェクト指向 (OO) プログラミングの経験がない場合は、基本的な概念を把握するために、オブジェクト指向 (OO) プログラミングの入門コースまたは少なくとも何らかのチュートリアルを参照することをお勧めします。

ただし、ここでは、オブジェクト指向プログラミング (OOP) を簡単に紹介して、迅速に説明します −

OOP 用語の概要

クラスの作成

クラス ステートメントは、新しいクラス定義を作成します。クラスの名前は、キーワード class の直後に続きます 次のようにコロンが続きます −

class ClassName:
   'Optional class documentation string'
   class_suite

以下は、単純な Python クラスの例です −

class Employee:
   'Common base class for all employees'
   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

インスタンス オブジェクトの作成

クラスのインスタンスを作成するには、クラス名を使用してクラスを呼び出し、その __init__ に任意の引数を渡します メソッドは受け入れます。

"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)

属性へのアクセス

オブジェクトのドット演算子を使用して、オブジェクトの属性にアクセスします。クラス変数は、次のようにクラス名を使用してアクセスされます-

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

さて、すべての概念をまとめる −

ライブデモ
#!/usr/bin/python

class Employee:
   'Common base class for all employees'
   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

"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
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  # Add an 'age' attribute.
emp1.age = 8  # Modify 'age' attribute.
del emp1.age  # Delete 'age' attribute.

通常のステートメントを使用して属性にアクセスする代わりに、次の関数を使用できます −

hasattr(emp1, 'age')    # Returns true if 'age' attribute exists
getattr(emp1, 'age')    # Returns value of 'age' attribute
setattr(emp1, 'age', 8) # Set attribute 'age' at 8
delattr(empl, 'age')    # Delete attribute 'age'

組み込みのクラス属性

すべての Python クラスは組み込み属性に従い、他の属性と同様にドット演算子を使用してアクセスできます −

上記のクラスについて、これらすべての属性にアクセスしてみましょう −

ライブデモ
#!/usr/bin/python

class Employee:
   'Common base class for all employees'
   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__: Common base class for all employees
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount':
<function displayCount at 0xb7c84994>, 'empCount': 2, 
'displayEmployee': <function displayEmployee at 0xb7c8441c>, 
'__doc__': 'Common base class for all employees', 
'__init__': <function __init__ at 0xb7c846bc>}

オブジェクトの破棄 (ガベージ コレクション)

Python は不要なオブジェクト (組み込み型またはクラス インスタンス) を自動的に削除して、メモリ領域を解放します。使用されなくなったメモリ ブロックを Python が定期的に再利用するプロセスは、ガベージ コレクションと呼ばれます。

Python のガベージ コレクターは、プログラムの実行中に実行され、オブジェクトの参照カウントがゼロになるとトリガーされます。オブジェクトを指すエイリアスの数が変化すると、オブジェクトの参照カウントも変化します。

オブジェクトの参照カウントは、新しい名前が割り当てられるか、コンテナー (リスト、タプル、または辞書) に配置されると増加します。 del で削除すると、オブジェクトの参照カウントが減少します 、その参照が再割り当てされているか、その参照が範囲外になっています。オブジェクトの参照カウントがゼロになると、Python はそれを自動的に収集します。

a = 40      # Create object <40>
b = a       # Increase ref. count  of <40> 
c = [b]     # Increase ref. count  of <40> 

del a       # Decrease ref. count  of <40>
b = 100     # Decrease ref. count  of <40> 
c[0] = -1   # Decrease ref. count  of <40> 

通常、ガベージ コレクターが孤立したインスタンスを破棄し、そのスペースを再利用することに気付くことはありません。しかし、クラスは特別なメソッド __del__() を実装できます 、デストラクタと呼ばれ、インスタンスが破棄されようとしているときに呼び出されます。このメソッドは、インスタンスによって使用されるメモリ以外のリソースをクリーンアップするために使用される場合があります。

この __del__() デストラクタは、破棄されようとしているインスタンスのクラス名を出力します −

ライブデモ
#!/usr/bin/python

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, "destroyed"

pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # prints the ids of the obejcts
del pt1
del pt2
del pt3

上記のコードを実行すると、次の結果が生成されます-

3083401324 3083401324 3083401324
Point destroyed

注意 − 理想的には、クラスを別のファイルに定義してから、import を使用してメイン プログラム ファイルにインポートする必要があります。

クラス継承

ゼロから始める代わりに、新しいクラス名の後の括弧内に親クラスをリストすることにより、既存のクラスから派生させてクラスを作成できます。

子クラスはその親クラスの属性を継承し、それらの属性を子クラスで定義されているかのように使用できます。子クラスは、親のデータ メンバーとメソッドをオーバーライドすることもできます。

構文

派生クラスは、親クラスと同じように宣言されます。ただし、継承元の基本クラスのリストは、クラス名の後に指定されます −

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

ライブデモ
#!/usr/bin/python

class Parent:        # define parent class
   parentAttr = 100
   def __init__(self):
      print "Calling parent constructor"

   def parentMethod(self):
      print 'Calling parent method'

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

   def getAttr(self):
      print "Parent attribute :", Parent.parentAttr

class Child(Parent): # define child class
   def __init__(self):
      print "Calling child constructor"

   def childMethod(self):
      print 'Calling child method'

c = Child()          # instance of child
c.childMethod()      # child calls its method
c.parentMethod()     # calls parent's method
c.setAttr(200)       # again call parent's method
c.getAttr()          # again call parent's method

上記のコードが実行されると、次の結果が生成されます-

Calling child constructor
Calling child method
Calling parent method
Parent attribute : 200

同様に、次のように複数の親クラスからクラスを駆動できます −

class A:        # define your class A
.....

class B:         # define your class B
.....

class C(A, B):   # subclass of A and B
.....

issubclass() または isinstance() 関数を使用して、2 つのクラスとインスタンスの関係を確認できます。

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

親クラスのメソッドはいつでもオーバーライドできます。親のメソッドをオーバーライドする理由の 1 つは、サブクラスに特別な機能または異なる機能が必要な場合があるためです。

ライブデモ
#!/usr/bin/python

class Parent:        # define parent class
   def myMethod(self):
      print 'Calling parent method'

class Child(Parent): # define child class
   def myMethod(self):
      print 'Calling child method'

c = Child()          # instance of child
c.myMethod()         # child calls overridden method

上記のコードが実行されると、次の結果が生成されます-

Calling child method

基本オーバーロード メソッド

次の表に、独自のクラスでオーバーライドできる一般的な機能をいくつか示します −

Sr.No. メソッド、説明、サンプル呼び出し
1

__init__ (自己 [,args...])

コンストラクター (任意の引数付き)

サンプル呼び出し:obj =className(args)

2

__del__(自己)

デストラクタ、オブジェクトを削除します

サンプル呼び出し:del obj

3

__repr__(自己)

評価可能な文字列表現

サンプル呼び出し:repr(obj)

4

__str__(自己)

印刷可能な文字列表現

サンプル呼び出し:str(obj)

5

__cmp__ (自己, x )

オブジェクト比較

サンプル呼び出し:cmp(obj, x)

演算子のオーバーロード

2 次元ベクトルを表す Vector クラスを作成したとします。プラス演算子を使用してそれらを加算するとどうなりますか?ほとんどの場合、Python が怒鳴るでしょう。

ただし、 __add__ を定義することはできます クラスのメソッドでベクトル加算を実行すると、プラス演算子は期待どおりに動作します-

ライブデモ
#!/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)

データ隠蔽

オブジェクトの属性は、クラス定義の外で見える場合と見えない場合があります。 2 つのアンダースコアのプレフィックスを付けて属性に名前を付ける必要があり、それらの属性は部外者に直接表示されません。

ライブデモ
#!/usr/bin/python

class JustCounter:
   __secretCount = 0
  
   def count(self):
      self.__secretCount += 1
      print self.__secretCount

counter = JustCounter()
counter.count()
counter.count()
print counter.__secretCount

上記のコードが実行されると、次の結果が生成されます-

1
2
Traceback (most recent call last):
   File "test.py", line 12, in <module>
      print counter.__secretCount
AttributeError: JustCounter instance has no attribute '__secretCount'

Python は、名前をクラス名を含むように内部的に変更することで、これらのメンバーを保護します。 object._className__attrName などの属性にアクセスできます .最後の行を次のように置き換えると、うまくいきます-

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

上記のコードが実行されると、次の結果が生成されます-

1
2
2

Python

  1. C# クラスとオブジェクト
  2. Python データ型
  3. Python 演算子
  4. Python pass ステートメント
  5. Python 辞書
  6. Python カスタム例外
  7. Python オブジェクト指向プログラミング
  8. Python の継承
  9. Java シングルトン クラス
  10. 自動ビジョンオブジェクト追跡
  11. Python の type() と isinstance() と例