6

私は完全な初心者ではありませんが、Pythonにはかなり慣れていません。今日プロジェクトに取り組んでいる間、私はちょうどアイデアを思いつき、「自己」の使い方について疑問に思いました。私はこれについてしばらく読んでいますが、それが常に必要かどうかはまだわかりません。私の質問は、クラスのインスタンスとインスタンスのパラメーター/変数のみに関するものです。この質問は、すべてのインスタンスに影響するクラス変数に関するものではありません

class C:
    def __init__(self, parent = None):
        super(C, self).__init__(parent)
        self.some_temp_var = AnotherClass()
        self.important_property = self.some_temp_var.bring_the_jewels()

ins_c = C()
print ins_c.important_property 

上記のコードでは、両方の変数宣言 ( some_temp_varimportant_property ) の前にselfを使用しています。

後で外部 (インスタンスが作成された場所) から **important_property**にアクセスし、場合によってはそれを変更する必要があります。

しかし、AnotherClass() のインスタンスやそれを指す変数 ( some_temp_var ) にアクセスする必要はありません。it クラスのインスタンスが 1 回だけ必要であり、そのメソッド Bring_the_jewels を 1 回だけ実行して、 important_property の値を入力する必要があります

その変数も宣言する前に、まだ self を使用する必要がありますか?

self.some_temp_var = ....
self.important_property = ....

またはそれができます:

some_temp_var = ....
self.important_property = ....

ご協力ありがとうございました。

Ps。私は長い方法で研究を行いました。私の英語および/またはCSの知識が不足しているため、現在存在する複製を見つけられなかった可能性がありますが、検索を行い、多くの検索を行いました. この質問を「重複」または「非建設的」と呼ぶ前に、よく読んでください。これは明確な答えのある質問であり、非常に重要で複雑な問題です。ご理解いただきありがとうございます。

4

3 に答える 3

8

を使用self.some_temp_varしない場合は、コンストラクターの後にガベージ コレクションされるローカル変数を定義しています。

したがってself、インスタンスで永続化する必要があるインスタンス属性を定義する場合は、必要です。パブリックにする必要があるかプライベートにする必要があるかは、命名の問題です。_for protected または__for privateを前に付けます。

some_temp_varがコンストラクターの単なる一時であり、二度と必要ない場合は、いいえ、必要ありませんself。永続性とメンバー属性についてです。self単一のメソッド内で変数を操作するという純粋な事実は必要ありません。

これを考えてみてください...some_temp_var実際の結果値に到達するために構築する巨大なデータ構造があるとしたらどうでしょうか? self一時変数またはインスタンスを削除するまでメモリを解放しないため、一時変数を保存するために使用したくありません。不要になったときにクリーンアップする必要があります。

于 2012-12-30T20:34:04.367 に答える
4

その場合、変数はまったく必要ないように見えます:

class C:
    def __init__(self, parent=None):
        super(C, self).__init__(parent)
        self.important_property = AnotherClass().bring_the_jewels()

あなたのコメントに応えて:

自己を置く必要がありますか。中に作成、参照、使用される場合は、その前に__init__

いいえ、あなたはしません。その場合、通常の変数を使用すると、オブジェクトは終了後にガベージコレクションされ__init__ます。

class C:
    def __init__(self, parent = None):
        super(C, self).__init__(parent)
        some_temp_var = AnotherClass()
        self.important_property = some_temp_var.bring_the_jewels()
于 2012-12-30T20:34:11.250 に答える
3

Python は、「パブリック」変数と「プライベート」変数を実際には区別しません。「self.something = value」を使用して自分自身の名前に割り当てるものはすべて、そのインスタンスのインスタンス変数になります。

Python には、ここで関連する 2 つの規則があります。

1) Python のフィールドまたはメソッドにはアンダースコア ('_') がプレフィックスとして付けられ、ユーザーに「これはこのクラス以外では問題にならない」ことを伝えます。単一のアンダースコアは、C# のような言語が「保護された」変数と呼ぶものを多かれ少なかれ識別する従来の方法です。これは実装の内部にあり、このクラスと派生クラスを除いてそのままにしておく必要があります。二重アンダースコアは、C# の「プライベート」変数のようなものです。これは内部的なものであり、派生クラスであってもそのままにしておく必要があり、オーバーライドすることはできません。

class Example(object):
    def __init__(self)
       self._protected= "protected"
       self.__private = "private"
       self.public = "public"

class Derived(Example):
    pass

d = Derived()
print d._protected
>> protected
print d.__private
>> AttributeError: 'Derived' object has no attribute '__private'

厳密に言えば、単一のアンダースコアは単なる表記規則です。二重のアンダースコアは、継承を防ぐためにクラス内の名前を実際に壊します。

2)AnotherClassが実際にハングアップする場合、およびAnotherClassインスタンスを操作するとAnotherClassの状態に影響する場合、プロパティデコレータを使用する可能性があります。

class C:
    def __init__(self, parent = None):
        super(C, self).__init__(parent)
        self._private = AnotherClass()

    @property
    def public(self):
       return self._private.some_method_on_AnotherClass()

    @public.setter
    def set_pub(self, val)
       self._private.set_value_on_AnotherClass(val)
于 2012-12-30T20:46:43.333 に答える