python - `vars` 和 `setattr` 和有什么区别?

标签 python sqlalchemy

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 between vars and setattr.

这是我尝试过的

变量失败

代码

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 对象时工作正常,但在 中失败修改(名称未更改)。

日志/测试

我尝试在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()

输出

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

但是当我 checkin mysql时,它不起作用

setattr成功

然后我在函数 set_option_parameters 中更改为 setattr(var, option_key, options[option_key])

它在初始化和修改中都运行良好,并且 application.__dict__ 的输出是相同的!

最佳答案

From the docs对于变量:

Objects such as modules and instances have an updateable dict attribute; however, other objects may have write restrictions on their dict attributes (for example, classes use a types.MappingProxyType to prevent direct dictionary updates).

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

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

关于python - `vars` 和 `setattr` 和有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54897575/

相关文章:

python - Eclipse中不同项目使用不同版本的python

python - 使用特定列绘制二维 NumPy 数组

python - SQLAlchemy ORM 检查列是否为外键

python - 如何使用 pytest 对 sqlalchemy orm 类进行单元测试

python - Sklearn 字符串的余弦相似度,Python

python - 将字母序列传递给 CNN - Keras

python - 为什么插入和删除在 Windows 7 上比在 Mac 10.9 上花费的时间长 100 多倍?

python - 如何使用 session 而不必传递它[SqlAlchemy]

python - SQLAlchemy Automap 不会为没有主键的表创建类

python - 在 SQLAlchemy : could not translate host name to address: Name or service not known 中创建引擎