ホームページ バックエンド開発 Python チュートリアル Python での self の使用法を理解する

Python での self の使用法を理解する

Mar 03, 2017 pm 03:17 PM

私が初めて Python でクラスの書き方を学び始めたとき、それが非常に面倒だと感じました。なぜ、定義するときに必要なのに、呼び出すときに必要ないのですか。なぜ、キーストロークの数を減らすために内部的に簡素化できないのでしょうか?この記事を読めば、あなたの疑問はすべて理解できるでしょう。

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

説明する例:

class Test:
  def prt(self):
    print(self)
    print(self.__class__)
 
t = Test()
t.prt()
ログイン後にコピー

実行結果は次のとおりです

<__main__.Test object at 0x000000000284E080>
<class &#39;__main__.Test&#39;>
ログイン後にコピー

上記の例から、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 &#39;__main__.Test&#39;>
ログイン後にコピー

継承する際にどのインスタンスに渡されるかは、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(&#39;self in Desc: %s &#39; % self )
    print(self, ins, cls)
class Test:
  x = Desc()
  def prt(self):
    print(&#39;self in Test: %s&#39; % 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 &#39;__main__.Test&#39;>
ログイン後にコピー

ほとんどの子供用靴は、なぜ 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 &#39;__main__.Test&#39;>
ログイン後にコピー

余談: 多くの場合、記述子クラスは記述子を呼び出すインスタンスが誰であるかを知る必要があるため、記述子クラスにはインスタンスを呼び出すクラスを表す 2 番目のパラメーター ins があります。 t.x の 3 行目の実行結果の 2 番目の項目が であることがわかります。 Test.x を使用して呼び出した場合、インスタンスがないため None が返されます。

OOの本質からPythonで自己を理解する

たとえば、ユーザーのデータを操作したいとします。ユーザーのデータには名前と年齢が含まれています。プロセス指向を使用する場合、実装は次のようになります。

def user_init(user,name,age): 
  user[&#39;name&#39;] = name 
  user[&#39;age&#39;] = age 
 
def set_user_name(user, x): 
  user[&#39;name&#39;] = x 
 
def set_user_age(user, x): 
  user[&#39;age&#39;] = x 
 
def get_user_name(user): 
  return user[&#39;name&#39;] 
 
def get_user_age(user): 
  return user[&#39;age&#39;] 
 
myself = {} 
user_init(myself,&#39;kzc&#39;,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(&#39;kzc&#39;,17) 
print u.GetName() 
print u.GetAge()
ログイン後にコピー

上記の例からわかるように、オブジェクト指向は実際には非常に便利ですが、ほとんどの人はそれをうまく抽象化せず、うまくカプセル化せず、間違って使用しています。

概要

    selfは定義時に定義する必要がありますが、呼び出されたときに自動的に渡されます。
  • selfの名前は規定されていませんが、合意に従ってselfを使用するのが最善です
  • self は、呼び出されたときに常にクラスのインスタンスを参照します。

Python での self の使用法の理解に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は? LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は? Apr 01, 2025 pm 05:09 PM

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

あるデータフレームの列全体を、Python内の異なる構造を持つ別のデータフレームに効率的にコピーする方法は? あるデータフレームの列全体を、Python内の異なる構造を持つ別のデータフレームに効率的にコピーする方法は? Apr 01, 2025 pm 11:15 PM

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

人気のあるPythonライブラリとその用途は何ですか? 人気のあるPythonライブラリとその用途は何ですか? Mar 21, 2025 pm 06:46 PM

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

正規表現とは何ですか? 正規表現とは何ですか? Mar 20, 2025 pm 06:25 PM

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

uvicornは、serving_forever()なしでhttpリクエストをどのように継続的に聞いていますか? uvicornは、serving_forever()なしでhttpリクエストをどのように継続的に聞いていますか? Apr 01, 2025 pm 10:51 PM

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

Pythonの仮想環境の目的を説明してください。 Pythonの仮想環境の目的を説明してください。 Mar 19, 2025 pm 02:27 PM

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

文字列を介してオブジェクトを動的に作成し、Pythonでメソッドを呼び出す方法は? 文字列を介してオブジェクトを動的に作成し、Pythonでメソッドを呼び出す方法は? Apr 01, 2025 pm 11:18 PM

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

See all articles