[英]What is the difference between `vars` and `setattr`?
After failing to use vars to change db.Model(flask-sqlalchemy) value I solved it by using
setattr
instead, but after reading doc still don't get the difference betweenvars
andsetattr
.在使用 vars 更改 db.Model(flask-sqlalchemy) 值失败后,我改用
setattr
解决了这个问题,但在阅读文档后仍然没有得到vars
和setattr
之间的区别。
Here is what I have tried这是我尝试过的
vars
vars
失败from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def set_option_parameters(var, option_keys, options):
for option_key in options:
if option_key in option_keys and options[option_key] is not None:
vars(var)[option_key] = options[option_key]
# setattr(var, option_key, options[option_key])
class Application(db.Model):
id = db.Column(db.BigInteger(), primary_key=True, autoincrement=True)
name = db.Column(db.VARCHAR(20), nullable=False)
...
def __init__(self, options):
option_keys = set(["name"])
set_option_parameters(self, option_keys, options)
def modification(self, options):
modifiable = set(["name"])
set_option_parameters(self, modifiable, options)
vars(var)[option_key] = options[option_key]
works fine in initing a Application
object , but failed in modification
( name
didn't change). vars(var)[option_key] = options[option_key]
在初始化Application
对象时工作正常,但modification
失败( name
没有改变)。
And I tried to print the application.__dict__
before db.session.commit()
, it did be modified!我试图在
db.session.commit()
之前打印application.__dict__
,它确实被修改了!
application = Application.query.filter_by(id=args["id"]).first()
# args["name"] is not None
app.logger.info(f"Before: {application.__dict__}")
application.modification(args)
app.logger.info(f"After: {application.__dict__}")
db.session.commit()
output输出
[2019-02-27 11:22:59,209] INFO in equipmentbaseapplicationhandler: Before:{'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x7f718ac2b588>, 'id': 9, 'name': 'old_name'}
[2019-02-27 11:22:59,209] INFO in equipmentbaseapplicationhandler: After:{'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x7f718ac2b588>, 'id': 9, 'name': 'new_name'}
BUT When I checked in mysql, it did not work但是当我检查 mysql 时,它不起作用
setattr
setattr
成功Then I changed to setattr(var, option_key, options[option_key])
in function set_option_parameters
.然后我在函数
set_option_parameters
更改为setattr(var, option_key, options[option_key])
。
it works good in both init and modification, and the output of application.__dict__
is the same! init 和
application.__dict__
都很好用, application.__dict__
的输出是一样的!
From the docs for vars
:来自
vars
的文档:
Objects such as modules and instances have an updateable dict attribute;
模块和实例等对象具有可更新的dict属性; however, other objects may have write restrictions on their dict attributes (for example, classes use a types.MappingProxyType to prevent direct dictionary updates).
但是,其他对象可能对其dict属性有写限制(例如,类使用 types.MappingProxyType 来防止直接字典更新)。
Looking through the SQLAlchemy source code (for instance, here ), it is a common pattern to return a copy of some_model.__dict__
when accessed, rather than returning the __dict__
itself.查看 SQLAlchemy 源代码(例如, 这里),在访问时返回
some_model.__dict__
的副本是一种常见模式,而不是返回__dict__
本身。 So you are likely updating a copy rather than the original.因此,您可能正在更新副本而不是原件。 Otherwise, it's possible that the dict is getting overwritten by the attributes themselves, even if the dict changes.
否则,即使 dict 更改,dict 也可能被属性本身覆盖。
setattrs
is the correct pattern, and is more explicit. setattrs
是正确的模式,而且更加明确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.