Python3 オブジェクト指向


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

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

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


オブジェクト指向技術の紹介

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

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

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

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

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

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

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

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

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

他のプログラミング言語と比較して、Pythonは新しい構文やセマンティクスをできるだけ追加せずにクラスメカニズムを追加します。

Python のクラスは、オブジェクト指向プログラミングのすべての基本機能を提供します。クラスの継承メカニズムにより、複数の基本クラスが許可され、派生クラスは基本クラス内のメソッドをオーバーライドでき、基本クラス内の同じ名前のメソッドを呼び出すことができます。 。

オブジェクトには、任意の量および種類のデータを含めることができます。

クラス定義

構文形式は次のとおりです:

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

クラスがインスタンス化された後、そのプロパティを使用できるようになります。実際、クラスが作成された後、そのプロパティにはクラス名を通じてアクセスできます。

クラス オブジェクト

クラス オブジェクトは、属性参照とインスタンス化という 2 つの操作をサポートします。

属性参照は、Python のすべての属性参照と同じ標準構文 obj.name を使用します。

クラスオブジェクトが作成された後は、クラス名前空間内のすべての名前が有効な属性名になります。したがって、クラス定義が次のようになっている場合:

#!/usr/bin/python3

class MyClass:
    """一个简单的类实例"""
    i = 12345
    def f(self):
        return 'hello world'

# 实例化类
x = MyClass()

# 访问类的属性和方法
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 f 输出为:", x.f())

クラスをインスタンス化します:

# 实例化类
x = MyClass()
# 访问类的属性和方法

上記は、新しいクラス インスタンスを作成し、オブジェクトをローカル変数 x に割り当てます。x は空のオブジェクトです。

上記のプログラムを実行した出力結果は次のとおりです:

MyClass 类的属性 i 为: 12345
MyClass 类的方法 f 输出为: hello world

多くのクラスは初期状態のオブジェクトを作成する傾向があります。したがって、クラスは次のように __init__() という名前の特別なメソッド (コンストラクター) を定義する場合があります。

def __init__(self):
    self.data = []

クラスが __init__() メソッドを定義している場合、クラスのインスタンス化操作は自動的に __init__() メソッドを呼び出します。したがって、次の例では、次のように新しいインスタンスを作成できます:

x = MyClass()

もちろん、__init__() メソッドにはパラメーターを含めることができ、そのパラメーターは __init__() を通じてクラスのインスタンス化操作に渡されます。例:

>>> class Complex:
...     def __init__(self, realpart, imagpart):
...         self.r = realpart
...         self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)

クラスのメソッド

クラス内では、def キーワードを使用してクラスのメソッドを定義できます。一般的な関数定義とは異なり、クラス メソッドにはパラメータ self が含まれている必要があり、これが最初のパラメータです。パラメータ:

#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

# 实例化类
p = people('php',10,30)
p.speak()

Execute 上記プログラムの出力結果は次のとおりです:

php 说: 我 10 岁。

Inheritance

Python はクラスの継承もサポートしています。言語が継承をサポートしていない場合、クラスは意味を持ちません。派生クラスの定義は以下の通りです

class DerivedClassName(BaseClassName1):
    <statement-1>
    .
    .
    .
    <statement-N>

基底クラス内に同じメソッド名があっても、サブクラスを使用する際に指定されていない場合は、基底クラスの括弧内の順序に注意する必要があります。 , Pythonは左から右に検索します。 つまり、サブクラスでメソッドが見つからない場合、左から右に検索して、そのメソッドが基本クラスに含まれているかどうかを確認します。


BaseClassName (例の基本クラス名) は、派生クラスと同じスコープ内で定義する必要があります。クラスに加えて、式も使用できます。これは、基本クラスが別のモジュールで定義されている場合に非常に便利です:

class DerivedClassName(modname.BaseClassName):

Instance

#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))



s = student('ken',10,60,3)
s.speak()

上記のプログラムを実行した出力は次のとおりです:

ken 说: 我 10 岁了,我在读 3 年级

多重継承

Python複数の継承形式のサポートも制限されています。多重継承のクラス定義は以下の例のようになります。

class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-N>

親クラス内に同じメソッド名が存在するが、使用時に指定されていない場合は、親クラスの順序に注意する必要があります。それをサブクラスに含めると、Python は左から右に検索します。 つまり、サブクラスでメソッドが見つからない場合は、左から右に検索して、親クラスにそのメソッドが含まれているかどうかを確認します。

#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))

#另一个类,多重继承之前的准备
class speaker():
    topic = ''
    name = ''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))

#多重继承
class sample(speaker,student):
    a =''
    def __init__(self,n,a,w,g,t):
        student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)

test = sample("Tim",25,80,4,"Python")
test.speak()   #方法名同,默认调用的是在括号中排前地父类的方法

上記のプログラムを実行した出力結果は次のとおりです:

我叫 Tim,我是一个演说家,我演讲的主题是 Python

メソッドの書き換え

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

#!/usr/bin/python3

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

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

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

上記のプログラムを実行した出力結果は次のとおりです:

调用子类方法

クラスの属性とメソッド

クラスのプライベート属性

__private_attrs: 2つのアンダースコアで始まり、属性がプライベートであることが宣言されますクラス外で使用したり、直接アクセスしたりすることはできません。クラス self.__private_attrs 内のメソッドで使用される場合。

クラスのメソッド

クラス内では、defキーワードを使用してクラスのメソッドを定義できます。一般的な関数定義とは異なり、クラスメソッドにはパラメータselfが含まれている必要があり、それが最初のパラメータです

。クラスのメソッド

__private_method: 2 つのアンダースコアで始まるメソッドはプライベート メソッドとして宣言され、クラス外から呼び出すことはできません。クラス内で slef.__private_methods を呼び出します。

例は次のとおりです:

#!/usr/bin/python3

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)  # 报错,实例不能访问私有变量

上記のプログラムを実行した出力結果は次のとおりです:

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

クラスの独自メソッド:

  • __init__: オブジェクト生成時に呼び出されるコンストラクタ

  • __del__ : オブジェクトを解放するときに使用される破壊関数

  • __repr__ : 印刷、変換

  • __setitem__ : インデックスに従って値を割り当てる

  • __getitem__: インデックスに従って値を取得

  • __len__:長さの取得

  • __cmp__:比較演算

  • __call__:関数呼び出し

  • __add__:加算演算

  • __sub__:減算演算

  • __mul__:乗算演算

  • __div__:除算演算

  • __mod__:剰余演算

  • __pow__: 演算子のオーバーロード

Python は、クラスの独自メソッドをオーバーロードすることもできます。 例は次のとおりです。

#!/usr/bin/python3

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)

上記のコードの実行結果は次のとおりです。れーれー