简体   繁体   中英

Python class return list of dictionaries as dot notation

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.

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 ( xy ) but in your case much more simpler to maintain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM