{vars`和`setattr`有什么区别?

时间:2019-02-27 03:31:14

标签: python sqlalchemy

  

在无法使用vars更改db.Model(flask-sqlalchemy)值之后,我改用了setattr来解决它,但是在阅读文档后仍然没有得到vars和{ {1}}。

这是我尝试过的

setattr中失败

代码

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]对象,但在Application中失败(modification不变)。

记录/测试

我尝试在name之前打印application.__dict__,但确实对其进行了修改!

db.session.commit()

输出

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()

但是当我在mysql中签入时,它不起作用

成功[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'}

然后我在功能setattr中更改为setattr(var, option_key, options[option_key])

它在初始化和修改中都很好,并且set_option_parameters的输出是相同的!

1 个答案:

答案 0 :(得分:1)

From the docs for vars

  

对象(例如模块和实例)具有可更新的 dict 属性;但是,其他对象可能对其 dict 属性具有写限制(例如,类使用type.MappingProxyType来防止直接字典更新)。

查看SQLAlchemy源代码(例如here),这是一种常见的模式,在访问时返回some_model.__dict__的副本,而不是返回__dict__本身。因此,您可能会更新副本而不是原始副本。否则,即使字典更改,该字典也有可能被属性本身覆盖。

setattrs是正确的模式,更明确。