1from inspect import isfunction
2
3
4def logic_mixin_factory(mass, mass_attr_name, material, material_attr_name, float_method_name):
5 def error_handler(error):
6 def handler(func):
7 def decorator(*args, **kwargs):
8 try:
9 return func(*args, **kwargs)
10 except error:
11 return False
12 return decorator
13 return handler
14
15 class WitchMixin:
16
17 @error_handler(AttributeError)
18 def _light_as_duck(self):
19 return getattr(self, mass_attr_name) == mass
20
21 @error_handler(AttributeError)
22 def _burns_like_wood(self):
23 return getattr(self, material_attr_name) == material
24
25 @error_handler(AttributeError)
26 def _floats_like_duck(self):
27 return isfunction(getattr(self, float_method_name))
28
29 def is_a_witch(self):
30 if self._light_as_duck() or self._burns_like_wood() or self._floats_like_duck():
31 return 'Burn her!'
32 return 'No, but it\'s a pity, cuz she looks like a witch!'
33 return WitchMixin
34
35
36# logic_mixin_factory = lambda m, m_a, w, w_a, f: type('WitchMixin', (), {'is_a_witch': lambda _: ("No, but it's a pity, cuz she looks like a witch!", "Burn her!")[getattr(_, m_a, None) == m or getattr(_, w_a, None) == w or isfunction(getattr(_, f, None))]})
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Виктор Бечев
09.11.2023 10:01Зависи, ако имаш подобен случай, където поведението ти при хендълване на грешка е много ясно дефинирано и еднакво за много функции - да. В повечето случаи надали това би било вярно условие, но не виждам нищо грешно в подхода.
Правили сме подобни неща в production код, където драйвери фейлваха по един и същ начин, просто в нашия случай не беше `return False` а нещо различно, но handling-а беше еднотипен.
П.П. Ха, сладко, не знаех, че `getattr` има default value!
|
Костадин Русалов
09.11.2023 09:50Може да се мине и без такъв декоратор в тази задача, но искам да питам дали е ок така да се хендълват грешки.
|