Я хотел бы заменить экземпляр объекта другим экземпляром внутри метода, подобного этому:
class A:
def method1(self):
self = func(self)
Объект извлекается из базы данных.
Я хотел бы заменить экземпляр объекта другим экземпляром внутри метода, подобного этому:
class A:
def method1(self):
self = func(self)
Объект извлекается из базы данных.
Маловероятно, что замена переменной "self" выполнит все, что вы пытаетесь сделать, чего не может быть просто достигнуто путем сохранения результата func (self) в другой переменной. "self" - это фактически локальная переменная, определенная только для продолжительности вызова метода, используемого для передачи в экземпляре класса, который работает. Замена self фактически не заменит ссылки на исходный экземпляр класса, принадлежащего другим объектам, и не создаст прочную ссылку на новый экземпляр, который ему был назначен.
Да, все, что произойдет, это то, что вы не сможете ссылаться на текущий экземпляр вашего класса 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
Это не прямой ответ на вопрос, но в сообщениях ниже есть решение, для которого амируче пытался:
И вот пример рабочего кода (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()
(я не профессионал и не могу ответить, почему это так).
Насколько я понимаю, если вы пытаетесь заменить текущий объект другим объектом того же типа (предположим, что func не изменит тип объекта) из функции-члена. Я думаю, что это достигнет этого.
class A:
def method1(self):
newObj = func(self)
self.__dict__.update(newObj.__dict__)
Можно использовать самоопределение в методе, чтобы изменить класс экземпляра на производный класс.
Конечно, можно было бы назначить его новому объекту, но затем использование нового объекта рябилось бы через остальную часть кода в методе. Переориентируя его на себя, остальная часть метода не тронута.
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
...
Но помимо такого особого варианта использования я не вижу никаких преимуществ для замены себя.
Да, в этом нет ничего плохого. Ненавистники пусть ненавидят. (Глядя на вас, Пичарм с вашим 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
?
Я назначил self методом init. Моя причина заключалась в том, что объект можно создать, читая файл pickle (быстрый), но если этот файл рассоса отсутствует, объект может быть полностью пересчитан (медленный).