2009-08-01 18 views
20

私はこのような方法の内側に別のインスタンスがオブジェクト・インスタンスを交換したいと思います:メソッド内で同じタイプの別のオブジェクトで自己オブジェクトを置き換えることは安全ですか?

class A: 
    def method1(self): 
     self = func(self) 

オブジェクトは、データベースから検索されます。

+1

も参照してください。http://stackoverflow.com/questions/1015592/why-is-self-in-python-objects-immutable – ShreevatsaR

答えて

34

「自己」の変数を交換して達成することはほとんどありません何でも」:

def func(obj): 
    obj.var_a = 123 
    obj.var_b = 'abc' 

は次に、この操作を行います。何をすべきfunc(self)

は、インスタンスの変数を変更することですfunc(self)の結果を別の変数に格納するだけでは実現できませんでした。 'self'は事実上、操作されているクラスのインスタンスを渡すために使われるメソッド呼び出しの間だけ定義されたローカル変数です。自己置換は、他のオブジェクトが保持するクラスの元のインスタンスへの参照を実際には置き換えず、割り当てられた新しいインスタンスへの永続的な参照を作成しません。

6

ありがとうございます。変更する前に他の変数をselfに設定しない限り、クラスAの現在のインスタンスを参照することはできません。読みにくいコードを作成します。

他の変数と同じように、変数のみを変更していることに注意してください。 self = 123を実行することは、abc = 123と同じです。 selfは、メソッド内の現在のインスタンスへの参照のみです。 selfを設定してインスタンスを変更することはできません。

class A: 
    def method1(self): 
     func(self) # No need to assign self here 
7

それは質問に直接答えではないが、以下の記事でやってみました何amiroucheのために解決策があります:

そしてここでのコードを働いていますサンプル(Python 3.2.5)。

class Men: 
    def __init__(self, name): 
     self.name = name 

    def who_are_you(self): 
     print("I'm a men! My name is " + self.name) 

    def cast_to(self, sex, name): 
     self.__class__ = sex 
     self.name = name 

    def method_unique_to_men(self): 
     print('I made The Matrix') 


class Women: 
    def __init__(self, name): 
     self.name = name 

    def who_are_you(self): 
     print("I'm a women! My name is " + self.name) 

    def method_unique_to_women(self): 
     print('I made Cloud Atlas') 


men = Men('Larry') 
men.who_are_you() 
#>>> I'm a men! My name is Larry 
men.method_unique_to_men() 
#>>> I made The Matrix 


men.cast_to(Women, 'Lana') 
men.who_are_you() 
#>>> I'm a women! My name is Lana 
men.method_unique_to_women() 
#>>> I made Cloud Atlas 

self.__class__ないself.__class__.__name__。私。この技術はクラス名を置き換えるだけでなく、実際にはクラスのインスタンスを変換します(少なくとも両方とも同じid())。また、1)「オブジェクト自身のメソッドで同じタイプの別のオブジェクトで自己オブジェクトを置き換えるのが安全かどうかわかりません。 2)同じタイプのオブジェクトだけでなく、異なるタイプのオブジェクトでも動作します。 3)それはamirouche wantとまったく同じではありません。Class(args)のようなクラスを初期化することはできません。Class()(私はプロではないので、このような理由で答えることはできません)。

0

メソッドの自己割り当てを使用して、インスタンスのクラスを派生クラスに変更することができます。

もちろん、それを新しいオブジェクトに割り当てることはできますが、新しいオブジェクトの使用はメソッド内の残りのコードに波及します。それを自己に再分類すると、残りのメソッドはそのまま残ります。

class aclass: 

    def methodA(self): 
     ... 
     if condition: 
      self = replace_by_derived(self) 
      # self is now referencing to an instance of a derived class 
      # with probably the same values for its data attributes 

     # all code here remains untouched 
     ... 
     self.methodB() # calls the methodB of derivedclass is condition is True 
     ... 

    def methodB(self): 
     # methodB of class aclass 
     ... 

class derivedclass(aclass): 
    def methodB(self): 
     #methodB of class derivedclass 
     ... 

ただし、このような特殊な使用例を除いて、私は自己を置き換える利点はありません。

5

私の知る限り、現在のオブジェクトをメンバ関数から同じ型の別のオブジェクト(オブジェクト型を変更しないと仮定して)と置き換えようとしている場合は、理解しています。これで実現すると思います。

class A: 
def method1(self): 
    newObj = func(self) 
    self.__dict__.update(newObj.__dict__) 
+0

は非常にうんざりですが、私のために働いています - ありがとう! – alex314159

0

はい、これは問題ありません。言いたい奴には言わせとけ。 (あなたのPycharmをあなたのin most cases imaginable, there's no point in such reassignment and it indicates an errorで見て)。あなたがこれを行うことができます

状況は次のとおりです。

some_method(self, ...): 

    ... 

    if(some_condition): 
     self = self.some_other_method() 

    ... 

    return ... 

確かに、あなたはいくつかの他の変数へselfを再割り当てすることにより、メソッド本体を起動することができていますが、通常は他のparametresと、なぜそれをしないならばselfでそれをしますか?

関連する問題