Чем можно заменить eval?

Рейтинг: 0Ответов: 1Опубликовано: 10.06.2023

Есть следующая функция:

async def get_objects(
        model: BaseObjectCRUD,
        scheme: BaseModel,
        session: AsyncSession

) -> JSONResponse:

    if obj_list := await model.read(session):

        response_scheme = [
            {
                attr: eval(f'lambda obj, attr: obj.{attr}')(obj, attr)
                for attr in scheme.schema().get('properties')
            }
            for obj in obj_list
        ]
        return JSONResponse(
            content=response_scheme,
            status_code=HTTP_200_OK,
        )

    else:
        return NotFoundJSONResponse

Получаем obj_list, который представляет из себя список orm сущностей. Из pydantic scheme, которая прокидывается в качестве аргумента, получаем строковые названия атрибутов, которые сохраянем в attr, а затем с помощью eval обращаемся из obj к этому атрибуту.
Хотелось бы обойтись без eval, но не знаю как можно сделать тоже самое иначе.

Ответы

▲ 0Принят

Украду у @vitidev

async def get_objects(
        model: BaseObjectCRUD,
        scheme: BaseModel,
        session: AsyncSession,
) -> JSONResponse:
    if obj_list := await model.read(session):
        response_scheme = [
            {
                attr: getattr(obj, attr)
                for attr in scheme.schema().get('properties')
            }
            for obj in obj_list
        ]
        return JSONResponse(
            content=response_scheme,
            status_code=HTTP_200_OK,
        )
    else:
        return NotFoundJSONResponse