[Python] Python シリーズ チュートリアル -- Python3 オブジェクト指向 (28)

序文

過去のレビュー:

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

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

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

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

  • クラス (Class): 同じプロパティとメソッドを持つオブジェクトのコレクションを記述するために使用されます。コレクション内のすべてのオブジェクトに共通のプロパティとメソッドを定義します。オブジェクトはクラスのインスタンスです。
  • メソッド: クラスで定義された関数。
  • クラス変数: クラス変数は、インスタンス化されたオブジェクト間で共通です。クラス変数は、クラス内および関数本体の外で定義されます。クラス変数は通常、インスタンス変数としては使用されません。
  • データ メンバー: クラス変数またはインスタンス変数は、クラスとそのインスタンス オブジェクトに関連するデータを処理するために使用されます。
  • メソッドの書き換え: 親クラスから継承したメソッドがサブクラスのニーズを満たせない場合は、メソッドを書き換えることができます。このプロセスはメソッド オーバーライドと呼ばれ、メソッドの書き換えとも呼ばれます。
  • ローカル変数: メソッドで定義された変数は、現在のインスタンスのクラスにのみ適用されます。
  • インスタンス変数: クラス宣言では、属性はインスタンス変数と呼ばれる変数で表されます。インスタンス変数は、self で修飾された変数です。
  • 継承: つまり、派生クラス (派生クラス) は、基底クラス (基底クラス) のフィールドとメソッドを継承します。継承により、派生クラスのオブジェクトを基本クラスのオブジェクトとして扱うこともできます。たとえば、次のような設計があります。Dog タイプのオブジェクトは、「is-a」関係 (たとえば、Dog is an Animal) をシミュレートする Animal クラスから派生します。
  • インスタンス化: クラスのインスタンス、つまりクラスの具体的なオブジェクトを作成します。
  • オブジェクト: クラスによって定義されたデータ構造のインスタンス。オブジェクトは 2 つのデータ メンバー (クラス変数とインスタンス変数) とメソッドで構成されます。

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

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

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

クラス定義

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

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

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

クラスオブジェクト

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

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

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

例 (Python 3.0 以降)

#!/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 に割り当てます。ここで、x は空のオブジェクトです。

上記のプログラムを実行すると、出力は次のようになります。

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

クラスには、次のように、クラスがインスタンス化されるときに自動的に呼び出されるinit () と呼ばれる特別なメソッド (コンストラクター)があります。

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

このクラスは _ init _() メソッドを定義しており、クラスのインスタンス化により _ init _() メソッドが自動的に呼び出されます。クラス MyClass は次のようにインスタンス化され、対応する _ init _() メソッドが呼び出されます。

x = MyClass()
もちろん、\ init () メソッドにはパラメータを含めることができ、それらのパラメータは\ init () を介してクラスのインスタンス化に渡されます。例えば:

例 (Python 3.0 以降)

#!/usr/bin/python3
 
class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i)   # 输出结果:3.0 -4.5

self はクラスではなくクラスのインスタンスを表します

クラス メソッドには、通常の関数との特別な違いが 1 つだけあります。追加の最初のパラメータ名が必要であり、慣例により self と呼ばれます。

class Test:
    def prt(self):
        print(self)
        print(self.__class__)
 
t = Test()
t.prt()
```python
以上实例执行结果为:
```python
<__main__.Test instance at 0x100771878>
__main__.Test

実行結果から、self はクラスのインスタンスを表し、現在のオブジェクトのアドレスを表し、self.class はクラスを指していることがわかります。

self は Python キーワードではないため、 runob に置き換えると通常どおり実行できます。

class Test:
    def prt(runoob):
        print(runoob)
        print(runoob.__class__)
 
t = Test()
t.prt()

上記の例の実行結果は次のようになります。

<__main__.Test instance at 0x100771878>
__main__.Test

クラスメソッド

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

例 (Python 3.0 以降)

#!/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('runoob',10,30)
p.speak()

上記のプログラムを実行すると、出力は次のようになります。

runoob 说:10 岁。

継承する

Python はクラスの継承もサポートしていますが、言語が継承をサポートしていない場合、クラスは意味がありません。派生クラスの定義は次のようになります。

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

サブクラス (派生クラス DerivedClassName) は、親クラス (基本クラス BaseClassName) のプロパティとメソッドを継承します。

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

class DerivedClassName(modname.BaseClassName):

例 (Python 3.0 以降)

#!/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 は左から右へ、つまりメソッドが見つからない場合に検索します。サブクラスでは、メソッドが親クラスに含まれているかどうかを左から右に検索します。

例 (Python 3.0 以降)

#!/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

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

親クラスのメソッドの機能がニーズを満たせない場合は、サブクラスで親クラスのメソッドをオーバーライドできます。例は次のとおりです。

例 (Python 3.0 以降)

#!/usr/bin/python3
 
class Parent:        # 定义父类
   def myMethod(self):
      print ('调用父类方法')
 
class Child(Parent): # 定义子类
   def myMethod(self):
      print ('调用子类方法')
 
c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法
super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法

super()関数は、親クラス(スーパークラス)を呼び出すためのメソッドです。

上記のプログラムを実行すると、出力は次のようになります。

调用子类方法
调用父类方法

クラスのプロパティとメソッド

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

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

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

self という名前は必須ではありません。これを使用することもできますが、規則に従って self を使用することをお勧めします。

##クラスのプライベート メソッド
__private_method: 2 つのアンダースコアで始まり、メソッドをプライベート メソッドとして宣言します。このメソッドはクラスの外部ではなくクラスの内部でのみ呼び出すことができます。self.__private_methods。

インスタンスクラスのプライベート属性インスタンスは
次のとおりです。

例 (Python 3.0 以降)

#!/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'

クラスのプライベート メソッド インスタンスは次のとおりです。

例 (Python 3.0 以降)

#!/usr/bin/python3
 
class Site:
    def __init__(self, name, url):
        self.name = name       # public
        self.__url = url   # private
 
    def who(self):
        print('name  : ', self.name)
        print('url : ', self.__url)
 
    def __foo(self):          # 私有方法
        print('这是私有方法')
 
    def foo(self):            # 公共方法
        print('这是公共方法')
        self.__foo()
 
x = Site('菜鸟教程', 'www.runoob.com')
x.who()        # 正常输出
x.foo()        # 正常输出
x.__foo()      # 报错

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

  • _ init _ : オブジェクトの作成時に呼び出されるコンストラクター
  • _ del _ : デストラクター、オブジェクトを解放するときに使用されます。
  • _repr_ : 印刷、変換
  • _ setitem _ : インデックスによる割り当て
  • _ getitem _: インデックスによって値を取得します
  • _ len _: 長さを取得します
  • _ cmp _: 比較演算
  • _ call _: 関数呼び出し
  • _ add _: 加算演算
  • _ sub _: 減算
  • _mul_ : 乗算演算
  • _truediv_ :除算演算
  • _ mod _: 剰余演算
  • _pow_ :パワー

演算子のオーバーロード

Python は演算子のオーバーロードもサポートしています。クラスの独自メソッドをオーバーロードできます。例は次のとおりです。

例 (Python 3.0 以降)

#!/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)

上記のコードを実行した結果は次のようになります。

Vector(7,8)

おすすめ

転載: blog.csdn.net/u011397981/article/details/131099609