33 lines
1.0 KiB
Python
33 lines
1.0 KiB
Python
import functools
|
|
|
|
|
|
def rgetattr(obj, attr: str, safe: bool = False, *args, **kwargs):
|
|
"""
|
|
Version récursive de getattr pour utiliser une propriété chaînée même avec None au milieu.
|
|
exemples :
|
|
- rgetattr(obj, 'a.b.c')
|
|
- rgetattr(obj, 'a.b.c', safe=True)
|
|
|
|
:param obj: cible
|
|
:type obj: Any
|
|
|
|
:param attr: propriété qui peut être chaînée en séparant par '.'
|
|
:type attr: str
|
|
|
|
:param safe: indique qu'il faut tester la présence de l'attribut avec hasattr (utile pour les relations entre modèles Django), defaults to False
|
|
:type safe: bool
|
|
|
|
:return: valeur de l'attribut
|
|
:rtype: Any
|
|
"""
|
|
def _getattr(obj, attr):
|
|
return getattr(obj, attr, *args) if not safe or hasattr(obj, attr) else None
|
|
return functools.reduce(_getattr, [obj] + attr.split('.'))
|
|
|
|
def safe_rgetattr(obj, attr: str, safe: bool = False, *args, **kwargs):
|
|
"""
|
|
version safe de rgetattr
|
|
exemples : safe_rgetattr(obj, 'a.b.c')
|
|
"""
|
|
return rgetattr(obj, attr, safe=True, *args, **kwargs)
|