Python での self の使用法を理解する
私が初めて Python でクラスの書き方を学び始めたとき、それが非常に面倒だと感じました。なぜ、定義するときに必要なのに、呼び出すときに必要ないのですか。なぜ、キーストロークの数を減らすために内部的に簡素化できないのでしょうか?この記事を読めば、あなたの疑問はすべて理解できるでしょう。
self はクラスではなく、クラスのインスタンスを表します。
説明する例:
class Test: def prt(self): print(self) print(self.__class__) t = Test() t.prt()
実行結果は次のとおりです
<__main__.Test object at 0x000000000284E080> <class '__main__.Test'>
上記の例から、self がクラスのインスタンスを表すことは明らかです。そして self.class はクラスを指します。
selfはselfと書く必要はありません
多くの子供たちは最初に他の言語を学び、その後Pythonを学ぶので、常にselfをこのように書きたいのですが、大丈夫ですか?
もちろん、上記のコードを書き直してみましょう。
class Test: def prt(this): print(this) print(this.__class__) t = Test() t.prt()
をこれに変更すると、実行結果はまったく同じになります。
もちろん、確立された習慣を尊重し、自己を使用することが最善です。
self と書かないことはできますか
Python インタプリタ内で t.prt() を呼び出すと、Python は実際にそれを Test.prt(t) として解釈します。これは、 self を class のインスタンスに置き換えることを意味します。
興味のあるお子様は、上記の t.prt() 行を書き直すことができます。実行後の実際の結果はまったく同じになります。
実際、定義時に self を省略できないことは部分的に説明されていますので、試してみる必要がある場合は、以下を参照してください:
class Test: def prt(): print(self) t = Test() t.prt()
実行時のリマインダーエラーは次のとおりです: prt には定義時にパラメータがありません。 , しかし、実行するとパラメータが強制的に渡されました。
t.prt() は Test.prt(t) と同等であると上で説明したため、プログラムは追加のパラメーター t を渡したことを思い出させます。
Traceback (most recent call last): File "h.py", line 6, in <module> t.prt() TypeError: prt() takes 0 positional arguments but 1 was given
もちろん、定義でクラスインスタンスを渡さなくても大丈夫です。これはクラスメソッドです。
class Test: def prt(): print(__class__) Test.prt()
実行結果は以下の通り
<class '__main__.Test'>
継承する際にどのインスタンスに渡されるかは、selfが定義されているクラスのインスタンスではなく、渡されたインスタンスになります。
最初にコードを見てください
class Parent: def pprt(self): print(self) class Child(Parent): def cprt(self): print(self) c = Child() c.cprt() c.pprt() p = Parent() p.pprt()
実行結果は次のとおりです
<__main__.Child object at 0x0000000002A47080> <__main__.Child object at 0x0000000002A47080> <__main__.Parent object at 0x0000000002A47240>
説明:
インスタンスを参照する c.cprt() を実行するときに、理解に問題はありません。チャイルドクラスの。
しかし、c.pprt() を実行する場合、それは Child.pprt(c) と同等であるため、self は依然として Child クラスのインスタンスを参照します。pprt() メソッドは self 内で定義されていないため、調べる必要があります。継承ツリーを遡ると、pprt() メソッドが親クラス Parent に定義されていることがわかり、このメソッドは正常に呼び出されます。
記述子クラスでは、self は記述子クラスのインスタンスを参照します
まず例を見てみましょう:
class Desc: def __get__(self, ins, cls): print('self in Desc: %s ' % self ) print(self, ins, cls) class Test: x = Desc() def prt(self): print('self in Test: %s' % self) t = Test() t.prt() t.x
実行結果は次のとおりです。
self in Test: <__main__.Test object at 0x0000000002A570B8> self in Desc: <__main__.Desc object at 0x000000000283E208> <__main__.Desc object at 0x000000000283E208> <__main__.Test object at 0x0000000002A570B8> <class '__main__.Test'>
ほとんどの子供用靴は、なぜ Desc クラスで定義された self をそれを呼び出すインスタンス t にしてはいけないのかという疑問を持ち始めています。どのようにして Desc クラスのインスタンスになったのでしょうか?
注: ここで呼ばれているのは t.x です。これは、Test クラスのインスタンス t の属性 x であることを意味します。属性 x はインスタンス t で定義されていないため、クラス属性 x が見つかりました。この属性は Desc クラスのインスタンスである記述子属性であるため、ここには Test を使用するメソッドはありません。
次に、クラスを通じて属性 x を直接呼び出しても、同じ結果が得られます。
以下はt.xをTest.xに変更した結果です。
self in Test: <__main__.Test object at 0x00000000022570B8> self in Desc: <__main__.Desc object at 0x000000000223E208> <__main__.Desc object at 0x000000000223E208> None <class '__main__.Test'>
余談: 多くの場合、記述子クラスは記述子を呼び出すインスタンスが誰であるかを知る必要があるため、記述子クラスにはインスタンスを呼び出すクラスを表す 2 番目のパラメーター ins があります。 t.x の 3 行目の実行結果の 2 番目の項目が
たとえば、ユーザーのデータを操作したいとします。ユーザーのデータには名前と年齢が含まれています。プロセス指向を使用する場合、実装は次のようになります。
def user_init(user,name,age): user['name'] = name user['age'] = age def set_user_name(user, x): user['name'] = x def set_user_age(user, x): user['age'] = x def get_user_name(user): return user['name'] def get_user_age(user): return user['age'] myself = {} user_init(myself,'kzc',17) print get_user_age(myself) set_user_age(myself,20) print get_user_age(myself)
ユーザーに対するさまざまな操作にはユーザー パラメーターを渡す必要があることがわかります。
オブジェクト指向を使用する場合、ユーザー パラメーターを毎回やり取りする必要はありません。関連するデータと操作を 1 か所でバインドでき、このクラスのさまざまな場所からデータを簡単に取得できます。 データがクラス内のさまざまな場所からアクセスできる理由は、データが self にバインドされているためです。もちろん、そのメソッドの最初のパラメーターを self と呼ぶ必要はなく、単に Self という別の名前を付けることができます。大会。
以下はオブジェクト指向の実装であり、より構造化されており、明確で読みやすいことがわかります。
class User(object): def __init__(self,name,age): self.name = name self.age = age def SetName(self,name): self.name = name def SetAge(self,age): self.age = age def GetName(self): return self.name def GetAge(self): return self.age u = User('kzc',17) print u.GetName() print u.GetAge()
上記の例からわかるように、オブジェクト指向は実際には非常に便利ですが、ほとんどの人はそれをうまく抽象化せず、うまくカプセル化せず、間違って使用しています。
概要
- selfは定義時に定義する必要がありますが、呼び出されたときに自動的に渡されます。
- selfの名前は規定されていませんが、合意に従ってselfを使用するのが最善です
self は、呼び出されたときに常にクラスのインスタンスを参照します。
Python での self の使用法の理解に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









LinuxターミナルでPythonバージョンを表示する際の許可の問題の解決策PythonターミナルでPythonバージョンを表示しようとするとき、Pythonを入力してください...

PythonのPandasライブラリを使用する場合、異なる構造を持つ2つのデータフレーム間で列全体をコピーする方法は一般的な問題です。 2つのデータがあるとします...

この記事では、numpy、pandas、matplotlib、scikit-learn、tensorflow、django、flask、and requestsなどの人気のあるPythonライブラリについて説明し、科学的コンピューティング、データ分析、視覚化、機械学習、Web開発、Hの使用について説明します。

正規表現は、プログラミングにおけるパターンマッチングとテキスト操作のための強力なツールであり、さまざまなアプリケーションにわたるテキスト処理の効率を高めます。

UvicornはどのようにしてHTTPリクエストを継続的に聞きますか? Uvicornは、ASGIに基づく軽量のWebサーバーです。そのコア機能の1つは、HTTPリクエストを聞いて続行することです...

この記事では、Pythonにおける仮想環境の役割について説明し、プロジェクトの依存関係の管理と競合の回避に焦点を当てています。プロジェクト管理の改善と依存関係の問題を減らすための作成、アクティベーション、およびメリットを詳しく説明しています。

Pythonでは、文字列を介してオブジェクトを動的に作成し、そのメソッドを呼び出す方法は?これは一般的なプログラミング要件です。特に構成または実行する必要がある場合は...
