【Pythonを使いこなす100日】Day12: 基本構文とオブジェクト指向プログラミングの例_属性と継承

      目次

1 属性

1.1 属性の基本構文

1.2 計算用のプロパティを作成する

1.3 属性のセキュリティ保護メカニズム

2 継承

2.1 継承の基本構文

2.2 メソッドの書き換え

2.3 派生クラスで基本クラスの _init_() メソッドを呼び出す

3 まとめ 


         プロパティはクラスの特性またはデータ メンバーであり、整数、文字列、リストなどのさまざまなデータ型を含めることができます。属性を使用すると、クラスのさまざまな特性や動作を定義できます。

        継承とは、あるクラス (サブクラスと呼ばれる) が別のクラス (親クラスと呼ばれる) のプロパティとメソッドを継承できるようにするクラス間の関係です。継承を通じて、サブクラスは親クラスの関数を再利用でき、必要に応じて新しいプロパティやメソッドを追加することもできます。

  • プロパティはオブジェクトの状態またはデータを表し、オブジェクトの特性です。オブジェクト指向プログラミングでは、クラスはプロパティを定義でき、インスタンスはそれらのプロパティの具体的な値を持ちます。
  • 継承とはオブジェクト間の関係であり、あるクラスが別のクラスのプロパティとメソッドを継承することで、既存のコードを再利用したり、関数を拡張したりできます。
  • 継承により、クラス階層を確立し、抽象クラスから特定のサブクラスを継承できます。サブクラスは親クラスのすべてのプロパティとメソッドを持つことができ、必要に応じて独自の一意のプロパティとメソッドを追加することもできます。

1 属性

Python では、クラス内で変数を定義することで属性を作成できます。これらの変数はインスタンス変数またはプロパティと呼ばれます。すべてのインスタンス変数はクラスのインスタンスに属し、必要に応じて異なる値を割り当てることができます。

1.1 属性の基本構文

属性の定義:属性は通常、クラス内で定義され、クラス内で変数を宣言することによって属性を作成できます。属性は、インスタンス属性 (クラスのインスタンスに属する) またはクラス属性 (クラス自体に属する) にすることができます。

class MyClass:
    # 定义实例属性
    instance_var = 10
    
    def __init__(self):
        # 初始化实例属性
        self.name = "John"

属性へのアクセス:selfインスタンス属性には、クラスのメソッド内のキーワードを使用してアクセスできますクラス プロパティの場合は、クラス名を使用してアクセスできます。

class MyClass:
    class_var = 20
    
    def __init__(self):
        self.instance_var = 10
        
    def get_class_var(self):
        # 访问类属性
        return MyClass.class_var
    
    def get_instance_var(self):
        # 访问实例属性
        return self.instance_var

属性の変更:クラス メソッドは、selfキーワードを通じてインスタンス属性の値を変更できます。

class MyClass:
    def __init__(self):
        self.instance_var = 10
        
    def set_instance_var(self, value):
        # 修改实例属性的值
        self.instance_var = value

属性の可視性: Python では、デフォルトで、クラスのすべての属性はパブリックであり、クラスの外部からアクセスできます。プロパティをプライベートにしたい場合は、プロパティ名の前に 2 つのアンダースコアを追加できます__

class MyClass:
    def __init__(self):
        # 私有属性
        self.__private_var = 10
        
    def get_private_var(self):
        # 访问私有属性
        return self.__private_var
    
    def set_private_var(self, value):
        # 修改私有属性的值
        self.__private_var = value

プロパティのデコレータ:デコレータを使用して、@propertyクラスのメソッドをプロパティに変換できます。これにより、プロパティの使用時にアクセスされたかのようにメソッドを呼び出すことができます。

class MyClass:
    def __init__(self):
        self.__private_var = 10
        
    @property
    def private_var(self):
        # 使用装饰器将方法转换为属性
        return self.__private_var

例:

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

car1 = Car("Toyota", "Corolla", 2022)
car2 = Car("Honda", "Civic", 2021)

print(car1.make)  # 输出:Toyota
print(car2.year)  # 输出:2021

上の例では、Car というクラスを作成し、__init__初期化メソッドで 3 つのプロパティ (make、model、year) を定義しました。次に、Car クラスの 2 つのインスタンスを作成し、各インスタンスに異なる値を割り当てました。

1.2 計算用のプロパティを作成する

        Python では、@property デコレータを使用して計算用のプロパティを作成できます。計算プロパティは、値がインスタンス変数に直接格納されるのではなく、特定のメソッドを呼び出すことによって計算されるプロパティです。計算されたプロパティは、他のインスタンス変数の値から計算したり、複雑な計算ロジックを実行したりできます。

        計算されたプロパティの構文形式は、@property デコレーターを使用して作成できます。@property デコレータを使用すると、メソッドを、値がインスタンス変数に格納されるのではなく計算される読み取り専用プロパティに変えることができます。

        @property の構文形式は次のとおりです。

class ClassName:
    def __init__(self, ...):
        # 初始化实例变量

    @property
    def attribute_name(self):
        # 计算属性的逻辑
        return computed_value

上記の構文形式では次のようになります。

  • ClassNameはクラスの名前で、クラスを定義していることを示します。
  • ...__init__インスタンス変数を初期化するために使用されるメソッドのパラメータ リストです。
  • attribute_nameこれは計算されたプロパティの名前であり、実際の状況に応じて指定できます。
  • computed_value計算によって得られる属性値であり、実際の状況に応じて計算することができます。

メソッドは @property デコレーターを使用して計算プロパティとして定義でき、通常のプロパティと同様にアクセスできます。計算プロパティにアクセスする場合、実際には @property で修飾されたメソッドが呼び出され、そのメソッドの戻り値がプロパティ値として返されます。

@property デコレータを使用する場合は、次の点に注意する必要があります。

  1. 計算されたプロパティとインスタンス変数の名前は異なっている必要があります。そうしないと、無限再帰が発生します。
  2. 計算されたプロパティは読み取りのみが可能で、変更はできません。計算されたプロパティの値を変更する場合は、対応する setter メソッドを定義し、@property.setter デコレータを使用する必要があります。

以下は、計算プロパティを作成する方法を示す例です。

class Circle:
    def __init__(self, radius):
        self.radius = radius

    @property
    def diameter(self):
        return self.radius * 2

    @property
    def area(self):
        return 3.14 * (self.radius ** 2)

    @property
    def circumference(self):
        return 2 * 3.14 * self.radius

# 创建Circle对象
circle = Circle(5)

# 访问计算属性
print(circle.diameter)  # 输出:10
print(circle.area)  # 输出:78.5
print(circle.circumference)  # 输出:31.400000000000002

# 修改radius属性并重新计算计算属性
circle.radius = 8
print(circle.diameter)  # 输出:16
print(circle.area)  # 输出:201.12
print(circle.circumference)  # 输出:50.24

        上の例では、半径プロパティと 3 つの計算プロパティ (直径、面積、円周) を含む Circle というクラスを作成しました。@property デコレータを通じて、これら 3 つのメソッドを計算プロパティとして定義し、これらの計算プロパティにアクセスすることで計算結果を取得します。

        計算されたプロパティは、追加のストレージ領域を必要とせずにプロパティ値を動的に計算できるため、メモリとコードのメンテナンス コストが節約されます。実際のアプリケーションでは、計算プロパティは、オブジェクトの他のプロパティに基づいて関連する値を計算したり、複雑な数学的計算や論理演算を実行したりするためによく使用されます。

1.3 属性のセキュリティ保護メカニズム

Python では、アクセス制御を設定することで属性のセキュリティ メカニズムを設定し、属性への誤った変更やアクセスを防ぐことができます。Python では、パブリック アクセスとプライベート アクセスという 2 つの一般的に使用されるアクセス制御方法があります。

パブリック アクセス: パブリック アクセスは Python のデフォルトの属性アクセス方法です。つまり、すべての属性に直接アクセスして変更できます。この方法にはアクセス制御はなく、属性へのアクセスと変更は完全にオープンです。例えば:

class Circle:
    def __init__(self, radius):
        self.radius = radius

circle = Circle(5)
print(circle.radius)  # 输出:5
circle.radius = 8
print(circle.radius)  # 输出:8

プライベート アクセス: セキュリティ メカニズムを設定するには、プロパティ名の前に 2 つのアンダースコア「__」を追加して、プロパティをプライベート プロパティとして設定します。プライベート プロパティにはクラス内でのみアクセスでき、外部から直接アクセスしたり変更したりすることはできません。プライベート プロパティにアクセスするには、パブリック アクセス インターフェイスを介して間接的にアクセスできます。例えば:

class Circle:
    def __init__(self, radius):
        self.__radius = radius

    def get_radius(self):
        return self.__radius

    def set_radius(self, radius):
        if radius > 0:
            self.__radius = radius

circle = Circle(5)
print(circle.get_radius())  # 输出:5
# 试图直接访问私有属性将报错
# print(circle.__radius)  # 报错:'Circle' object has no attribute '__radius'

circle.set_radius(8)
print(circle.get_radius())  # 输出:8

上記の例では、属性名の前にアンダースコア「__」を 2 つ追加し、radius 属性をプライベート属性として設定します。プライベート属性にアクセスして変更するために、パブリック アクセス インターフェイス get_radius() および set_radius() を定義します。これらを通じて、プライベート属性に間接的にアクセスして変更できます。

プライベート属性とパブリック アクセス インターフェイスを使用すると、クラス内で属性のアクセスと変更を制御できるため、属性のセキュリティが実現されます。このようにして、プロパティが外部から不正に変更されるのを防ぎ、プロパティの完全性とデータのセキュリティを保護することができます。

2 継承

        継承はオブジェクト指向プログラミングにおける重要な概念であり、これにより、別の既存のクラス (親クラスと呼ばれる) のプロパティとメソッドを継承する新しいクラス (サブクラスと呼ばれる) を作成できます。サブクラスは親クラスのすべてのパブリック メンバーを継承でき、また独自のメンバーを追加することもできます。継承により、コードの再利用と編成がより簡単かつ効率的になります。

2.1 継承の基本構文

class ParentClass:
    # 父类的属性和方法

class ChildClass(ParentClass):
    # 子类继承父类的属性和方法,并可以添加自己的属性和方法

上記の構文では、最初に、いくつかのプロパティとメソッドを含む親クラス ParentClass を定義します。次に、サブクラス ChildClass を定義し、親クラス名 ParentClass を括弧内に指定します。サブクラス ChildClass は、親クラス ParentClass のすべてのプロパティとメソッドを継承し、独自のプロパティとメソッドを追加することもできます。

        Python では、親クラスを引数として子クラスに渡すことで継承を実現できます。サブクラスは親クラスのプロパティとメソッドを継承し、必要に応じて新しいプロパティとメソッドを追加できます。

        以下は、親クラスと子クラスを作成し、継承を通じて親クラスのプロパティとメソッドを取得する方法を示す簡単な例です。

# 定义父类
class Animal:
    def __init__(self, name, species):
        self.name = name
        self.species = species

    def make_sound(self):
        pass

# 定义子类,并继承父类Animal
class Dog(Animal):
    def __init__(self, name, breed):
        # 调用父类的构造函数
        super().__init__(name, species="Dog")
        self.breed = breed

    def make_sound(self):
        return "Woof!"

# 创建子类对象
dog = Dog("Buddy", "Labrador")
print(dog.name)  # 输出:Buddy
print(dog.species)  # 输出:Dog
print(dog.breed)  # 输出:Labrador
print(dog.make_sound())  # 输出:Woof!

上の例では、名前と種の 2 つの属性と抽象メソッド make_sound を含む Animal 親クラスを定義しました。次に、Dog サブクラスを定義し、親クラス Animal のプロパティとメソッドを継承によって取得しました。サブクラスでは、独自のプロパティ Breeze を追加し、make_sound メソッドを実装しました。継承により、親クラスのコードをサブクラスで再利用したり、サブクラスの機能を拡張したりカスタマイズしたりすることができます。 

2.2 メソッドの書き換え

        メソッドのオーバーライド(メソッドオーバーライド)とは、オブジェクト指向プログラミングにおける重要な概念で、サブクラスが親クラスの既存メソッドをオーバーライド(書き換え)することで、メソッドのカスタマイズや拡張を実現します。親クラスと同じ名前のメソッドがサブクラスに定義されている場合、サブクラスのメソッドは親クラスのメソッドをオーバーライドするため、サブクラスのオブジェクトでメソッドが呼び出されたときに、親クラスの実装ではなくサブクラスの実装が実行されます。

        メソッドをオーバーライドするための基本的な構文は次のとおりです。

class ParentClass:
    def some_method(self):
        # 父类的方法实现

class ChildClass(ParentClass):
    def some_method(self):
        # 子类重写的方法实现

上記の構文では、some_method というメソッドを含む親クラス ParentClass を定義しました。次に、サブクラス ChildClass を定義し、その中の some_method メソッドを再定義します。サブクラス オブジェクトが some_method メソッドを呼び出すと、サブクラスのメソッド実装が実行されます。

以下は、サブクラスで親クラスのメソッドをオーバーライドする方法を示す例です。

# 定义父类
class Animal:
    def make_sound(self):
        return "Some generic sound"

# 定义子类,并继承父类Animal
class Dog(Animal):
    def make_sound(self):
        return "Woof!"

# 创建子类对象
dog = Dog()
print(dog.make_sound())  # 输出:Woof!

上の例では、汎用サウンド文字列を返す make_sound メソッドを含む親クラス Animal を定義しました。次に、Dog サブクラスを定義し、その中の make_sound メソッドをオーバーライドして「Woof!」を返します。サブクラスのオブジェクトを作成し、make_soundメソッドを呼び出すと、親クラスAnimalの実装ではなく、サブクラスDogで書き換えられたメソッドが実行され、「Woof!」が出力されます。これはメソッドのオーバーライドの役割であり、必要に応じてサブクラスが親クラスのメソッドをカスタマイズおよび拡張できるようにします。 

2.3 派生クラスで基本クラスの _init_() メソッドを呼び出す

派生クラス(サブクラス)内で基底クラス(親クラス)のメソッドを呼び出すには、関数__init__()を使用します。関数は、親クラスのメソッドとプロパティにアクセスするために使用される Python 組み込み関数です。super()super()

派生クラスのメソッドで関数を__init__()使用すると、最初にサブクラスのコンストラクターで親クラスのコンストラクターを呼び出してから、サブクラス自体の初期化コードを追加できます。これにより、サブクラス オブジェクトがスーパークラスのプロパティで初期化されることが保証されます。super()

__init__()以下は、サブクラス内の基本クラスのメソッドを呼び出す方法を示す例です。

class ParentClass:
    def __init__(self, name):
        self.name = name

class ChildClass(ParentClass):
    def __init__(self, name, age):
        super().__init__(name)  # 调用父类的__init__方法
        self.age = age

# 创建子类对象
child = ChildClass("Alice", 25)
print(child.name)  # 输出:Alice
print(child.age)   # 输出:25

上の例では、プロパティを初期化するメソッドParentClassを含む親クラスを定義しました__init__()name

別のサブクラスが定義されChildClass、そのメソッド内で親クラスを呼び出すメソッド__init__()が使用され、サブクラス オブジェクトの初期化時に属性が設定されますsuper().__init__(name)__init__()name

次に、サブクラス独自の初期化コードを追加し、ageプロパティを設定しました。最後に、サブクラス オブジェクトを作成し、nameおよびage属性にアクセスして、__init__()基本クラス メソッドの呼び出しが正しいことを確認しました。

3 まとめ 

属性:

  • プロパティは、データの保存またはプロパティ値の計算に使用され、クラスのメンバーの 1 つです。
  • クラス本体で変数を宣言することで、クラス内でプロパティを定義できます。属性は、インスタンス属性 (クラスのインスタンスに属する) またはクラス属性 (クラス自体に属する) にすることができます。
  • インスタンス属性はselfキーワードを使用してクラスのメソッド内でアクセスおよび変更されますが、クラス属性はクラス名を使用してアクセスできます。
  • デコレータを使用して@propertyメソッドをプロパティに変換し、プロパティの計算とアクセス制御を可能にします。
  • プロパティ名の前に 2 つのアンダースコアを付けることで、プロパティをプライベートにできます__

継承:

  • 継承とは、オブジェクト指向プログラミングにおいてコードの再利用を実現するための仕組みで、クラス(派生クラス)が別のクラス(基底クラス)のプロパティやメソッドを継承することができます。
  • 派生クラスは、基本クラスのすべてのプロパティとメソッドを取得でき、派生クラスに新しいプロパティとメソッドを追加したり、基本クラスのメソッドをオーバーライドしたりできます。
  • 継承関係はクラス階層を形成し、サブクラスは親クラスの特性を継承し、さらに多くのサブクラスを派生できます。
  • 継承を使用すると、コードの重複が減り、コードの保守性とスケーラビリティが向上します。

おすすめ

転載: blog.csdn.net/qq_35831906/article/details/131877627