1

I'm confused how to access class variables while in methods. For example, what are the ways that the compare method below can use the class variable COURSES? I got it to work by adding self before calling COURSES (self.COURSES.items()), but is that correct? I feel like it is bad practice and I'm missing something, but I can't seem to find the answer. Thanks, everyone.

class Example:
    COURSES = {
    "Python Basics": {"Python", "functions", "variables",
                      "booleans", "integers", "floats",
                      "arrays", "strings", "exceptions",
                      "conditions", "input", "loops"},
    "Java Basics": {"Java", "strings", "variables",
                    "input", "exceptions", "integers",
        }


    def compare(self, arg):
        intersection_list = []
        for key, value in COURSES.items():
        if value & arg:
            intersection_list.append(key)
        return intersection_list
PPS
  • 69
  • 1
  • 8
  • 4
    Possible duplicate of [In Python how can I access "static" class variables within class methods](https://stackoverflow.com/questions/707380/in-python-how-can-i-access-static-class-variables-within-class-methods) – awesoon Aug 03 '18 at 08:43
  • That is fine practice. One key point of building methods within a class is so that you can utilize the class attributes via `self`. – Wold Aug 03 '18 at 08:44

2 Answers2

2

Yes, using self. COURSES is ok. Python has so called "data inheritance". When you write self. COURSES it looks for COURSES in self.__dict__. If the attribute is not found there, self.__class__.__dict__ is searched -- and your class attribute is found. If the attribute is not found is class's __dict__ parent classes are searched.

See also: https://www.python-course.eu/python3_class_and_instance_attributes.php

warvariuc
  • 57,116
  • 41
  • 173
  • 227
1

I got it to work by adding self before calling COURSES (self.COURSES.items()), but is that correct?

It is correct. By definition, attribute lookup starts at the instance, then goes through the class and its base classes.

What you should be mindful of is if and how you want to react to shadowing attributes.

  • self.COURSES allows instances and sub-classes to shadow the attribute for themselves.
  • type(self).COURSES allows sub-classes but not instances to shadow the attribute.
  • Example.COURSES never allows shadowing.

You can try the difference with this example:

class Lookup(object):
    ATTRIBUTE = 'Base'

    def lookup(self):
        print(self.ATTRIBUTE)       # instance, class and base
        print(type(self).ATTRIBUTE) # class and base
        print(Lookup.ATTRIBUTE)     # base


class SubLookup(Lookup):
    ATTRIBUTE = 'Sub'


print('>> base class')
Lookup().lookup()
print('>> sub class')
SubLookup().lookup()
print('>> instance')
foo = SubLookup()
foo.ATTRIBUTE = 'Instance'
foo.lookup()
MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119