我想在像这样的方法中用另一个实例替换一个对象实例:
class A:
def method1(self):
self = func(self)
从数据库中检索对象。
答案 0 :(得分:51)
替换'self'变量不太可能完成你想要做的任何事情,这不可能通过将func(self)的结果存储在不同的变量中来实现。 'self'实际上是一个局部变量,仅在方法调用的持续时间内定义,用于传入正在操作的类的实例。替换self实际上不会替换对其他对象所持有的类的原始实例的引用,也不会创建对分配给它的新实例的持久引用。
答案 1 :(得分:15)
据我所知,如果您尝试用成员函数替换当前对象与另一个相同类型的对象(假设func不会更改对象类型)。我认为这将实现那个
class A:
def method1(self):
newObj = func(self)
self.__dict__.update(newObj.__dict__)
答案 2 :(得分:10)
这不是这个问题的直接答案,但在下面的帖子中,有一个解决方案可以解决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那样:你不能像Class(args)
那样初级化,只能Class()
(我不是专业人士,也不能回答为什么会这样)。
答案 3 :(得分:6)
是的,所有这一切都将导致您无法引用班级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
答案 4 :(得分: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 :(得分:0)
是的,这没有任何问题。愤世嫉俗的人看什么都不顺眼。 (用你的in most cases imaginable, there's no point in such reassignment and it indicates an error
看着你的Pycharm。
您可以这样做的情况是:
some_method(self, ...):
...
if(some_condition):
self = self.some_other_method()
...
return ...
当然,您可以通过将self
重新分配给其他变量来启动方法体,但如果您通常不会对其他参数执行此操作,为什么要使用self
?
答案 6 :(得分:0)
在许多情况下,实现所需目标的一种好方法是再次调用__init__
。例如:
class MyList(list):
def trim(self,n):
self.__init__(self[:-n])
x = MyList([1,2,3,4])
x.trim(2)
assert type(x) == MyList
assert x == [1,2]
请注意,这带有一些假设,例如关于__init__
中设置的对象的全部更改。
答案 7 :(得分:0)
您可以使实例成为类的单例元素
并用@classmethod
标记方法。
from enum import IntEnum
from collections import namedtuple
class kind(IntEnum):
circle = 1
square = 2
def attr(y): return [getattr(y, x) for x in 'k l b u r'.split()]
class Shape(namedtuple('Shape', 'k,l,b,u,r')):
self = None
@classmethod
def __repr__(cls):
return "<Shape({},{},{},{},{}) object at {}>".format(
*(attr(cls.self)+[id(cls.self)]))
@classmethod
def transform(cls, func):
cls.self = cls.self._replace(**func(cls.self))
Shape.self = Shape(k=1, l=2, b=3, u=4, r=5)
s = Shape.self
def nextkind(self):
return {'k': self.k+1}
print(repr(s)) # <Shape(1,2,3,4,5) object at 139766656561792>
s.transform(nextkind)
print(repr(s)) # <Shape(2,2,3,4,5) object at 139766656561888>