1

there are two similar types of getter in python:

a[b]
a.b

To convert the string type to attribute type, I have built a chain assignment:

def assign(target, *args, suffix):
    ls = target
    for i in range(len(args) - 1):
        a = args[i]
        ns = SimpleNamespace()
        setattr(ls, a, ns)
        ls = ns
    setattr(ls, args[-1], suffix)
    return ls


# a = SimpleNamespace()
# assign(a, 'a', 'b', 'c', suffix={'name': 'james'})
# print(a.a.b.c)
# # {'name': 'james'}

however, now I need to work with dictionaries, nested dictionaries:

def resign(target, di):
    print(target)
    print(di)
    print()
    for k, v in di.items():
        if isinstance(v, dict):
            resign(target=k, di=v)
        else:
            pass


resign(
    target=SimpleNamespace(), 
    di={
        'v' : {
            'a': 1, 
            'b': 2, 
            'c': {
                'd': 3, 
            }
        }
    }
)
# namespace()
# {'v': {'a': 1, 'b': 2, 'c': {'d': 3}}}

# v
# {'a': 1, 'b': 2, 'c': {'d': 3}}

# c
# {'d': 3}

this is so far I have got. the expected result is that when I use attribute to get value on the object:

target.v
# {
#     'a': 1, 
#     'b': 2, 
#     'c': {
#         'd': 3, 
#     }
# }
target.v.a
# 1
target.v.c
# {'d': 3}
target.v.c.d
# 3

Sorry I tried many but I cannot work out the recursion. I will be very grateful if you can give me a hand.


why I need to do that:

in django, to avoid model template attribute conflicts, which in some written template for example I have {{ article.name }}, but now I need to pass in instance from another class which have a different attribute name: {{ question.title }}, instead of write one more template, in question view, I want to create a dataframe to represent question to fit to article, the reason I give up abstract class is that it has slots restrictions which cannot assign attribute if it's already a field name

Weilory
  • 2,621
  • 19
  • 35
  • 2
    I think the `AttrDict` class in this [answer of mine](https://stackoverflow.com/a/38034502/355230) might help because its contents can be accessed with either `[]` or `.` notation. (You many not need the `from_nested_dicts()` class method it has,) – martineau Apr 25 '22 at 13:43
  • @martineau this is terrific, thanks very much. – Weilory Apr 25 '22 at 13:54

0 Answers0