2009-08-01 17 views

risposta

34

E 'improbabile che la sostituzione la variabile 'sé' compirà ciò che si' cercando di fare, ciò non potrebbe essere realizzato memorizzando il risultato di func (self) in una variabile diversa. 'self' è effettivamente una variabile locale definita solo per la durata della chiamata al metodo, utilizzata per passare nell'istanza della classe su cui si sta operando. La sostituzione di sé non sostituirà effettivamente i riferimenti all'istanza originale della classe detenuta da altri oggetti, né creerà un riferimento permanente alla nuova istanza ad essa assegnata.

6

Sì, tutto ciò che accadrà è che non sarà possibile fare riferimento all'istanza corrente della classe A (a meno che non si imposti un'altra variabile su self prima di modificarla). Non lo consiglierei però, rende il codice meno leggibile.

Nota che stai cambiando solo una variabile, proprio come qualsiasi altra. Fare self = 123 equivale a fare abc = 123. self è solo un riferimento all'istanza corrente all'interno del metodo. Non è possibile modificare l'istanza impostando self.

Cosa func(self) dovrebbe fare è quello di modificare le variabili dell'istanza:

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

poi fare questo:

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

Non è una risposta diretta alla domanda, ma nei messaggi di seguito c'è una soluzione per quello che Amirouche cercato di fare:

Ed ecco il codice di lavoro esempio (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 

Annotare il self.__class__ e non self.__class__.__name__. Cioè questa tecnica non solo sostituisce il nome della classe, ma in realtà converte un'istanza di una classe (almeno entrambi hanno lo stesso id()). Inoltre, 1) non so se sia "sicuro sostituire un oggetto autonomo con un altro oggetto dello stesso tipo nel metodo [un oggetto proprio]"; 2) funziona con diversi tipi di oggetti, non solo con quelli che sono dello stesso tipo; 3) funziona non esattamente come voleva l'amirouche: non puoi iniziare la lezione come Class(args), solo Class() (non sono un professionista e non posso rispondere perché è così).

0

Si può usare l'autoassegnazione in un metodo, per cambiare la classe di istanza in una classe derivata.

Naturalmente è possibile assegnarlo a un nuovo oggetto, ma in seguito l'uso del nuovo oggetto si diffonde attraverso il resto del codice nel metodo. Riassegnandolo a se stesso, lascia intatto il resto del metodo.

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 
     ... 

Ma a parte questo caso di utilizzo speciale, non vedo alcun vantaggio in sostituzione di sé.

5

Per quanto ho capito, se si sta tentando di sostituire l'oggetto corrente con un altro oggetto dello stesso tipo (supponendo che func non cambierà il tipo di oggetto) da una funzione membro. Penso che ciò raggiungerà quello

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

sembra molto unpythonic ma ha funzionato per me - grazie! – alex314159

0

Sì, non c'è niente di sbagliato in questo. Odio porta odio. (Guardando a te Pycharm con il tuo in most cases imaginable, there's no point in such reassignment and it indicates an error).

Una situazione in cui si potrebbe fare questo è:

some_method(self, ...): 

    ... 

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

    ... 

    return ... 

Certo, si potrebbe avviare il corpo del metodo riassegnando self a qualche altra variabile, ma se che normalmente non farlo con altri parametri, perché Fallo con self?

Problemi correlati