В нашем приложении Django есть большие блоки кода, где мы хотим, чтобы исключение было вызвано, если значение, извлеченное из базы данных, равно None
.
Конечно, мы могли бы написать собственный аксессор для этого поведения, но для того, чтобы эти блоки кода были простыми, мы залатали обезьяны Model
:
def raise_error_on_none_model_values(func):
@wraps(func)
def wrapped(*args, **kwargs):
# execute function if already patched
already_patched = (
Model.__getattribute__ == _getattribute_raising_if_value_is_none
)
if already_patched:
return func(*args, **kwargs)
# patch
Model.__getattribute__ = _getattribute_raising_if_value_is_none
# execute function
try:
return func(**kwargs)
finally:
del Model.__getattribute__
return wrapped
Тем не менее, мы (конечно!) Сталкиваемся с проблемами при использовании многопоточности.
Я исследовал, могут ли помочь такие библиотеки, как wrapt или gevent, но я не уверен, могут ли они помочь.
Можно ли сделать потокобезопасный патч обезьяны? Есть ли лучший способ достичь того, что мы хотим сделать?