ホームページ  >  記事  >  バックエンド開発  >  オブジェクト指向 Python に関する 6 つの質問

オブジェクト指向 Python に関する 6 つの質問

王林
王林転載
2023-04-11 20:43:131103ブラウズ

この記事は、Python を初めて使用する友人向けに書かれており、次の質問を明確にすることを目的としています:

  • クラスとオブジェクトとは何ですか?
  • 関数があるのに、なぜクラスは必要ですか?
  • Python はパブリック/プロテクト/プライベートのプロパティ/メソッドをどのように定義しますか?プライベートは本当にプライベートですか?そうする目的は何ですか?
  • クラス関数、メンバーを定義する方法関数と静的関数は何ですか? 関数とは何ですか?
  • クラスは継承できますが、サブクラスを使用するには、親クラスの関数を使用する前に親クラスの関数を書き換える必要があります。そうしないと例外がスローされます。
  • 次の継承関係があります: A、B (A)、C(A)、D(B,C) それでは、D が初期化されるとき、A、B、C の初期化順序はどうなるでしょうか。 A は 2 回初期化されますか?

1. クラスとオブジェクトとは何ですか?

最初にオブジェクトについて話しましょう。オブジェクトには通常 2 つの意味があります。オブジェクトは、次の場合に目標となるものを指します。行動や思考、あるいは特にあなたが恋をしている人に対して。プログラミングの世界では、オブジェクトとは、コンピューター ロジックの客観的な世界に存在する人、物、オブジェクト、その他のエンティティをマッピングしたものです。

プログラミングするとき、マッピングしたいものにオブジェクトをマッピングできます。ただし、マッピングがより一般的であれば、コードは使いやすく理解しやすくなり、その後の迅速な反復と実行にさらに役立ちます。拡大。 。 Python の世界では、すべてがオブジェクトです。

クラスについて話しましょう。クラスは分類されたクラスであり、類似のもののコレクションを表し、Python キーワード クラスに対応します。

オブジェクトはクラス内の特定のものであり、クラスの初期化後に生成されます。通常、オブジェクトまたはエンティティとも呼ばれます。たとえば、女性はクラスであり、あなたのガールフレンドはオブジェクトです。

属性: ガールフレンドの肌の色、民族、血液型など、オブジェクトの特定の静的特性。

機能: オブジェクトの特定の動的能力。たとえば、ガールフレンドは歌ったり、ピアノを弾いたりできます。

上記の例は適切ではないかもしれませんが、理解が深まると幸いです。実際、より正確な定義は次のとおりです:

クラスとはオブジェクトのグループです。同じ属性と機能を持つコレクション。

2. 関数があるのに、なぜクラスが必要なのでしょうか?

関数はコードの再利用を解決するためのものですが、関数はプロセス思考であり、具体的すぎます。物事の重複が多いため、問題を抽象化する必要もあります。クラスは一種の抽象概念です。抽象クラスは再利用可能であり、複雑なビジネス ロジックに対処しやすく、プログラマーのプログラミング メモリの負担も軽減します。

クラスがなければ、全体に影響を与えるようなコードを山ほど書いて、あえて変更する必要がなくなるでしょう。クラスを使用すると、読みやすく、保守しやすく、拡張可能なコードを簡単に作成できます。

3. Python はパブリック/プロテクト/プライベートのプロパティ/メソッドをどのように定義しますか? プライベートが本当にプライベートであるかどうか、そうする目的は何ですか?

Python は、以下の点で protected/private に同意します。フォーム属性/メソッド:

  • __ はプライベートを意味します
  • __ は保護を意味します
  • 最初の 2 つを除いて、パブリックです

いわゆる合意、つまり、二重アンダースコアまたは単一アンダースコアで始まる変数やメソッドを見つけた場合、意識的にそれを変更したり、クラス外でアクセスしたりしないようにする必要があります。言い換えれば、Python はプログラマがその変数やメソッドにアクセスすることを妨げません。クラスのプライベート属性またはプライベート メソッド。Python は信頼できるプログラマを選択します。

パブリック プロパティへのアクセスと保護されたプロパティへのアクセスに違いはありません。プライベート プロパティにアクセスするには、これを行う必要があります:

object._ClassName__PrivateMember

4. クラス関数、メンバー関数、および静的関数を定義する方法関数とその関数は何ですか?

コメントを見てください:

class Document():

WELCOME_STR = 'Welcome! The context for this book is {}.'

def __init__(self, title, author, context):
print('__init__函数被调用')
self.title = title
self.author = author
self.__context = context

#类函数
@classmethod
def create_empty_book(cls, title, author):
return cls(title=title, author=author, context='nothing')

# 成员函数
def get_context_length(self):
return len(self.__context)

# 静态函数
@staticmethod
def get_welcome(context):
return Document.WELCOME_STR.format(context)
empty_book = Document.create_empty_book('What Every Man Thinks About Apart from Sex', 'Professor Sheridan Simove')
print(empty_book.get_context_length())
print(empty_book.get_welcome('indeed nothing'))

クラス関数は @classmethod で修飾されています。最初のパラメーターは、クラス自体を表す cls である必要があります。つまり、classmethod 関数 cls() でクラス コンストラクターを呼び出すことができ、それによって新しいインスタンスが生成されます。この時点から、その使用シナリオを推測できます。

  • コンストラクターを再度呼び出す必要があるとき、つまり、新しいインスタンス オブジェクトを作成するとき
  • コンストラクターを変更する必要はありません。既存のインスタンスのケースは新しいインスタンスを返します。

メンバー関数は非常に一般的で、オブジェクトによって直接呼び出すことができるメソッドです。最初のパラメーターは self である必要があります。

@staticmethod で修飾された静的関数は、通常、この関数の計算にクラスの変数が関与せず、クラスをインスタンス化せずに使用できることを意味します。つまり、関数間の関係がつまり、staticmethod で修飾された関数はクラスの外でも定義できます。クラス内で staticmethod を使用するか、utils.py に別の関数を記述するかで時々悩むことがあります。

5. クラスは継承できます。サブクラスを使用するには、親クラスの関数を書き直す必要があるようにするにはどうすればよいですか。そうでないと例外がスローされますか?

2 つのメソッド、2 番目1つをお勧めします。

最初の型:

class A:
def fun(self):
raise Exception("not implement")
class B(A):
pass

b = B()
b.fun()

2 番目の型:

from abc import ABCMeta,abstractmethod
class A(metaclass = ABCMeta):
@abstractmethod
def fun(self):
pass
class B(A):
pass

b = B()
b.fun()

6. 次の継承関係があります: A、B(A)、C(A)、D(B ,C) D が初期化されるとき、A、B、C の初期化順序は何ですか? A は 2 回初期化されますか?

---> B---
A--->D
---> C---

A、B、および C の初期化順序は何ですか?同様にコードを書いて見てみましょう。

方法は 2 つあります。最初の方法では A が 2 回初期化されますが、2 番目の方法では初期化されません。

最初のタイプ:

class A:
def __init__(self):
print("A is called")class B(A):
def __init__(self):
print("B is called")
A.__init__(self)class C(A):
def __init__(self):
print("C is called")
A.__init__(self)class D(B,C):
def __init__(self):
print("D is called")
B.__init__(self)
C.__init__(self)

d = D()

出力:

D is called
B is called
A is called
C is called
A is called

2 番目のタイプ:

class A:
def __init__(self):
print("enter A")
print("levave A")class B(A):
def __init__(self):
print("enter B")
super().__init__()
print("levave B")class C(A):
def __init__(self):
print("enter C")
super().__init__()
print("levave C")class D(B,C):
def __init__(self):
print("enter D")
super().__init__()
print("levave D")

d = D()

出力;

enter D
enter B
enter C
enter A
levave A
levave C
levave B
levave D

第一种方法非常明确的表明了菱形继承潜在的问题:一个基类的初始化函数可能被调用两次。在一般的工程中,这显然不是我们所希望的。

正确的做法应该是使用 super 来召唤父类的构造函数,而且 python 使用一种叫做方法解析顺序的算法(具体实现算法叫做 C3),来保证一个类只会被初始化一次。

也就是说,能用 super,就用 super。

以上がオブジェクト指向 Python に関する 6 つの質問の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事は51cto.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。