python变量引用意外地改变了行为
我想了解这种完全出乎意料的行为改变的原因是什么,以及如何实施。我来自JS世界,这很可能不可能以任何方式实现 通过遍历对象调用fn会得到与首次将此对象分配给新变量时不同的结果:python变量引用意外地改变了行为,python,django,Python,Django,我想了解这种完全出乎意料的行为改变的原因是什么,以及如何实施。我来自JS世界,这很可能不可能以任何方式实现 通过遍历对象调用fn会得到与首次将此对象分配给新变量时不同的结果: >>> from core.models import SomeModel >>> s = SomeModel.objects.get(id=45) >>> s.user.profile.needs_review True >>> s.user.pro
>>> from core.models import SomeModel
>>> s = SomeModel.objects.get(id=45)
>>> s.user.profile.needs_review
True
>>> s.user.profile.needs_review = False
>>> s.user.profile.needs_review
True
>>> profile = s.user.profile
>>> profile.needs_review
True
>>> profile.needs_review = False
>>> profile.needs_review
False
这确实令人不安,因为在我使用过的任何语言中,这都会执行类似的操作
顺便说一句,这是一个常规的django模型,但我更感兴趣的是知道可以使用什么样的语言资源来实现这种效果
为了更好地解释我为什么会这样做,我尝试通过执行以下操作在配置文件
模型上进行常规保存:
streamer.user.profile.needs_review = True
streamer.user.profile.save()
它没有起作用,但做了:
profile = streamer.user.profile
profile.needs_review = True
profile.save()
工作正常。如果对模型对象进行更改,则必须保存该对象,否则它将无法反映
>>> s.user.profile.needs_review = False
>>> s.save()
>>> s.user.profile.needs_review
False
下一行
>>> profile = s.user.profile
>>> profile.needs_review
True
它不会从数据库加载新数据,所以这就是为什么您会看到这种行为关于允许这种行为的python语言资源,您可以检查:
基本上,django使用它来抽象数据库查询,在您的示例中不作为常规对象。请显示您的
用户
模型。这是django的标准用户模型。如果运行.save(),它是否会更改
更改字段后?遍历外键关系将从数据库加载对象。如果没有持久化更改(对对象调用.save()
),则会从数据库中加载一个新副本,该副本没有您刚才所做的更改。最好保留对该对象的本地引用,进行更改并保存,而不重新遍历图形。例如,streamer.save()
也会保留更改,您的错误是再次遍历streamer.user.profile
。@enapupe:类似于什么?遍历、数据库数据反射、检测属性更改?我想我不清楚的是为什么将其分配给新变量会改变一切。当您将其分配给新变量时,它将执行属性的getter
功能,创建您正在编辑的对象的实例。不指定时,仍使用父对象。尽管如此,它并没有解释这种行为,但它在Django代码中。
class C:
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x