0

Can I hear your thoughts on ways to add attributes (instance variables, not methods) to a Python dictionary? For record keeping, I want to insert additional descriptive variables.

For concreteness, here is an example. I want line 2 to work :)

>>> x = {"fred": "male", "wilma": "female", "barney": "male"}
>>> x.show = "Flintstones"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'show'

The closest I've come to a solution is a class that has an instance variable along with the dictionary for feature information. That works fine, however it is a little bit tedious because all access to the dictionary must be wrapped in obj.x rather than just obj. I also can get a solution with a nested dictionary, but it introduces even more complicated code to interact with the lower level dictionary. We don't want to organize/sort the data by x.show, we just want to have access to that variable.

Here's why I think this might be possible. In the past, I've created Pandas DataFrame subclass so that I could have the Pandas DataFrame (2D storage) along with instance variables. The Pandas DataFrame works like a pandas data frame, but it has those additional metavariables as well. To make the Pandas DF Subclass work, there is some fancy dancing to declare the instance variables, but in the end it did work.

3
  • 2
    Name your variable flintstones instead of x and that might help solve the problem you're facing? Commented Jun 22, 2021 at 14:35
  • 1
    Did you mean x["show"] = "Flintstones"? Why would you want to add an attribute? Commented Jun 22, 2021 at 14:38
  • I apologize, I did not spot that previous one while searching. I've confirmed the answer on other thread, from 2012, still works. Commented Jun 23, 2021 at 0:57

1 Answer 1

1

One way is to derive from a dictionary:

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        self.x = "Flintstones"
        

a = AttrDict({"fred": "male", "wilma": "female", "barney": "male"})
a.x = "Wilma"

Edit: Ok I posted this simultaneously with the valid comment of wjandrea. I still leave the answer as a demo on how to instantiate your original dict. Warning: The data will be copied at this point.

If you instead assign the dictionary to an attribute of the class, the copying can be avoided, but to the price that you mentioned (you need to address the attribute each time) unless you overload the operators, e.g. __getitem__ and __setitem__.

Sign up to request clarification or add additional context in comments.

1 Comment

To me, this is very good idea. More detailed than answer from 2012, which was accepted for same question. stackoverflow.com/questions/11532060/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.