0

Imagine you have a class in python that returns:

d=[{'source_id': '1', 'source_desc': 'XML1'},
 {'source_id': '2', 'source_desc': 'XML2'},
 {'source_id': '3', 'source_desc': 'XML3'}]

Imagine the class is called:

class ddata():
    def __init__(var):
        self.var=method_class(var)

    def method_class(self,v):
        ´´´do stuff / dummy method´´´
        return v
        

Initializing:

mydata=ddata(d)

Is it possible in python to add a particular method to the class in order to allow the following: pseudocode:

mydata.1.source_desc (would be XML1)

EDIT The intention is that one, and only one of the keys is used as enter dot notation. in this case the numbers. the numbers are int or str. AND ARE NOT NECESSARILY consecutive, what invalidate solutions based on position on the returned list.

JFerro
  • 3,203
  • 7
  • 35
  • 88
  • 1
    see https://stackoverflow.com/questions/28345780/how-do-i-create-a-python-namespace-argparse-parse-args-value – balderman Sep 26 '21 at 13:30
  • 1
    and this https://stackoverflow.com/questions/16279212/how-to-use-dot-notation-for-dict-in-python as well. – balderman Sep 26 '21 at 14:35
  • 1
    You can't have `mydata.1.source_desc` as Python source code because `1` is not a valid identifier. Similar remarks apply to strings containing spaces, hash marks, Python operators, and so on. – BoarGules Sep 26 '21 at 15:43

1 Answers1

0

It is possible to use integers as identifiers in Python, contrary to what @BoarGules said. Just not in source code. Proof :

>>> class Foo: pass
>>> foo = Foo()
>>> foo.__setattr__("1", "a number!")
>>> foo.1
  File "<input>", line 1
    foo.1
        ^
SyntaxError: invalid syntax
>>> foo.__getattribute__("1")
'a number!'

So here is a solution :

from typing import Dict, List

d = [
    {'source_id': '1', 'source_desc': 'XML1'},
    {'source_id': '2', 'source_desc': 'XML2'},
    {'source_id': '3', 'source_desc': 'XML3'},
    {'source_id': 'forty_two', 'source_desc': 'XML42'}
]


class DData:
    def __init__(self, d: List[Dict[str, str]]):
        for line in d:
            source_id = line["source_id"]
            source_desc = line["source_desc"]
            self.__setattr__(source_id, source_desc)

    def __getitem__(self, item):
        return self.__getattribute__(item)


my_data = DData(d)
print(my_data["1"])  # XML1
print(my_data.forty_two)  # XML42
# print(my_data.1)  # SyntaxError: invalid syntax

I used __getitem__ because I find it more friendly than __getattribute__.

But using just a properly-defined dict would do the same, and be much simpler :

my_dict = {line["source_id"]: line["source_desc"] for line in d}
print(my_dict["1"])  # XML1
print(my_dict["forty_two"])  # XML42

I would recommend not using identifiers that you cannot write in source code (1). And I think using the "dict notation" (x["y"]) is not very different from the dot notation (x.y) but in your case much more simpler to maintain.

Lenormju
  • 4,078
  • 2
  • 8
  • 22
  • Also, I would recommend to settle on using either figures or names for numbers, not both at the same time. – Lenormju Sep 27 '21 at 09:10