В чем разница между `vars` и` setattr`? - PullRequest
0 голосов
/ 27 февраля 2019

После того, как не удалось использовать vars для изменения значения db.Model (flask-sqlalchemy), я решил это, используя вместо этого setattr, но после прочтения документа до сих пор не получил разницу между vars и 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 не изменился).

Log / Test

И я попытался напечатать 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()

вывод

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

НО Когда я зарегистрировался в mysql, он не работал

Успешно в setattr

Затем я изменил на setattr(var, option_key, options[option_key]) в функции set_option_parameters.

, он хорошо работает как при инициализации, так и при модификации, и вывод application.__dict__ равенто же самое!

1 Ответ

0 голосов
/ 04 марта 2019

Из документов для vars:

Такие объекты, как модули и экземпляры, имеют обновляемый атрибут dict ;однако другие объекты могут иметь ограничения записи для своих атрибутов dict (например, классы используют types.MappingProxyType для предотвращения прямого обновления словаря).

Просмотр исходного кода SQLAlchemy(например, здесь ), это обычный шаблон для возврата копии some_model.__dict__ при обращении к ней, вместо того, чтобы возвращать сам __dict__.Таким образом, вы скорее всего обновляете копию, а не оригинал.В противном случае, возможно, что диктат перезаписывается самими атрибутами, даже если он меняется.

setattrs - правильный шаблон и более явный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...