Подтвердить что ты не робот

Можно ли безопасно заменить объект-объект другим объектом того же типа в методе?

Я хотел бы заменить экземпляр объекта другим экземпляром внутри метода, подобного этому:

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

Объект извлекается из базы данных.

4b9b3361

Ответ 1

Маловероятно, что замена переменной "self" выполнит все, что вы пытаетесь сделать, чего не может быть просто достигнуто путем сохранения результата func (self) в другой переменной. "self" - это фактически локальная переменная, определенная только для продолжительности вызова метода, используемого для передачи в экземпляре класса, который работает. Замена self фактически не заменит ссылки на исходный экземпляр класса, принадлежащего другим объектам, и не создаст прочную ссылку на новый экземпляр, который ему был назначен.

Ответ 2

Да, все, что произойдет, это то, что вы не сможете ссылаться на текущий экземпляр вашего класса A (если вы не установите другую переменную в self, прежде чем изменять ее.) Я бы не рекомендовал ее хотя, это делает для менее читаемого кода.

Обратите внимание, что вы меняете только переменную, как и все остальные. Выполнение self = 123 совпадает с выполнением abc = 123. self - это только ссылка на текущий экземпляр внутри метода. Вы не можете изменить свой экземпляр, установив self.

Что func(self) должно делать, это изменить переменные вашего экземпляра:

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

Затем сделайте следующее:

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

Ответ 3

Это не прямой ответ на вопрос, но в сообщениях ниже есть решение, для которого амируче пытался:

И вот пример рабочего кода (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: вы не можете инициализировать класс вроде Class(args), только Class() (я не профессионал и не могу ответить, почему это так).

Ответ 4

Насколько я понимаю, если вы пытаетесь заменить текущий объект другим объектом того же типа (предположим, что func не изменит тип объекта) из функции-члена. Я думаю, что это достигнет этого.

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

Ответ 5

Можно использовать самоопределение в методе, чтобы изменить класс экземпляра на производный класс.

Конечно, можно было бы назначить его новому объекту, но затем использование нового объекта рябилось бы через остальную часть кода в методе. Переориентируя его на себя, остальная часть метода не тронута.

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

Но помимо такого особого варианта использования я не вижу никаких преимуществ для замены себя.

Ответ 6

Да, в этом нет ничего плохого. Ненавистники пусть ненавидят. (Глядя на вас, Пичарм с вашим in most cases imaginable, there no point in such reassignment and it indicates an error).

Ситуация, в которой вы можете это сделать:

some_method(self, ...):

    ...

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

    ...

    return ...

Конечно, вы можете запустить тело метода, переназначив self на какую-либо другую переменную, но если вы обычно не делали этого с другими параметрами, зачем это делать с помощью self?

Ответ 7

Я назначил self методом init. Моя причина заключалась в том, что объект можно создать, читая файл pickle (быстрый), но если этот файл рассоса отсутствует, объект может быть полностью пересчитан (медленный).