0

Please see my code snips below. get_simple_percentiles and get_simple_percentile are able to access simple_lut.__simple_lut_dict. However, get_another_percentile cannot access simple_lut.__another_lut. The name of the file is simple_lut.py.


class simple_lut(object):
    __simple_lut_fname = None # filename for the LUT (Look Up Table)
    __simple_lut_dict = {}    # Dictionary of LUTs, one for each task
    __another_lut_fname = None
    __another_lut = None

    def __init__(self, simple_lut_filename, another_lut_filename=None ):
        # load simple LUT
        # ...
        for idx, curr_task in enumerate( tasks ):
            # ...
            self.__simple_lut_dict[ curr_task ] = tmp_dict

        # load another LUT
        # ...
        self.__another_lut = tmp_dict

    def get_simple_percentiles(self, subject):
        # for each simple task, go from score to percentile
        # calls get_simple_percentile

    @staticmethod
    def get_simple_percentile(subject, task):
        # works fine here
        tmp_dict = simple_lut.__simple_lut_dict[task]

    @staticmethod
    def get_another_percentile(subject):
        # this always comes back as None!!1
        tmp_dict = simple_lut.__another_lut
Suhas C
  • 192
  • 1
  • 8
  • If you want to access a class attribute, why do you use staticmethods instead of classmethods? – MisterMiyagi Sep 12 '19 at 03:58
  • If the access returns None, you did successfully access the attribute - but its value is None. Since your code is incomplete, we cannot tell you why tmp_dict is None when you assign it. Please create a reproducible example. https://stackoverflow.com/help/minimal-reproducible-example – MisterMiyagi Sep 12 '19 at 04:02
  • Thanks for the comments! Re the second comment, the value of the variable is not None in the init function but None in the get_another_percentile function and no other code that touches the variable... Re the first comment, I chose static instead of class so that the method can't change any member variables. – Suhas C Sep 12 '19 at 04:25

1 Answers1

1

You only assign the attribute on the instance, not the class :

self.__another_lut = tmp_dict

The class still has the None value assigned initially. Either assign to the class or use regular methods on the instance.

simple_lut.__another_lut = tmp_dict

Assignment creates a new attribute on the instance, leaving the attribute (and value) on the class unchanged. Since the class does not see the instance attribute, it can only access the original class attribute. Modifying an attribute directly changes its value, without adding a new instance attribute on top.


Take note that your current approach (initialising the class, not the instance) is uncommon and breaks expected behavior of instances. Consider using instances without static data or not using a class at all, but a module.

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
  • Thank you! I still don't understand why it works for simple_lut.__simple_lut_dict but not simple_lut.__another_lut though... I was trying to create static members like in C++ or Java but apparently, as you say, this is not how things are typically done. A blog post talks about Python class attributes and how they can useful in certain cases: https://www.toptal.com/python/python-class-attributes-an-overly-thorough-guide – Suhas C Sep 12 '19 at 16:28
  • 1
    You never assign to ``__simple_lut.__simple_lut_dict`` - you directly modify its content. There is still only the one ``dict`` object on the class. – MisterMiyagi Sep 12 '19 at 16:40
  • Pardon my ignorance but what is the difference between directly modifying its content and assigning? It sounds like assigning using pointers which don't last... – Suhas C Sep 12 '19 at 19:20
  • 1
    @SuhasC Assignment creates a *new* attribute on the instance, leaving the attribute (and value) on the class unchanged. Since the class does not see the instance attribute, it can only access the original class attribute. Modifying an attribute directly changes its value, without adding a new instance attribute on top. If you are familiar with pointer languages (C, C++, ...) you may want to read this: https://stackoverflow.com/questions/13530998/are-python-variables-pointers-or-else-what-are-they/57380719#57380719 – MisterMiyagi Sep 12 '19 at 20:19
  • Wow, thanks! I ended up learning way more than I wanted to know about Python internals (). Is there any way I can mark your comment above as the solution? That's what helped me the most. – Suhas C Sep 12 '19 at 22:54
  • @SuhasC I've added the comment to the answer. – MisterMiyagi Sep 13 '19 at 17:56