Question

I am writing an extension to a library and I would like to register my new function with a dictionary of function pointers in the base class. My understanding is that the dictionary, since it is at the uppermost scope within a class, is static and should be update-able. However, when I try to update() the dictionary with the new function in the extended class it tells me that it is undefined. The following minimal example reproduces the error:

def somefunction1(v):
    return v

def somefunction2(v):
    return v

class SomeClass(object):
    dictionary = {'a':somefunction1}

class SomeExtensionClass(SomeClass):
    dictionary.update({'b':somefunction2})

Running it gives the following error

 9 
 10 class SomeExtensionClass(SomeClass):
 ---> 11         dictionary.update({'b':somefunction2})

NameError: name 'dictionary' is not defined

Since I cannot (reasonably) modify the original SomeClass is there any way around this?

Edit: The desired result is that SomeExtensionClass will have dictionary={'a':somefunction1, 'b':somefunction2}

Was it helpful?

Solution

If you want to modify SomeClass.dictionary, just refer to it as SomeClass.dictionary:

SomeClass.dictionary.update(whatever)

Variable lookup within a class statement doesn't look through the superclasses' attributes.

If you want a new dictionary, so SomeExtensionClass.dictionary is different from SomeClass.dictionary, you'll want to copy the original and update the copy:

class SomeExtensionClass(SomeClass):
    dictionary = SomeClass.dictionary.copy()
    dictionary.update(whatever)

OTHER TIPS

There are two reasonable ways to give SomeExtensionClass an updated dictionary:

  1. Update the original dictionary by referring to SomeClass.dictionary.
  2. Define a second dictionary variable for the derived class.

You can do the second like this:

class SomeExtensionClass(SomeClass):
    dictionary = dict(SomeClass.dictionary, b=somefunction2)

Which you should choose depends on who uses the dictionary and for what. If a SomeClass method uses the variable like this:

def foo(self):
    a = self.dictionary['a']()

The method will use the SomeExtensionClass dictionary for SomeExtensionClass objects. If OTOH it does:

def foo(self):
    a = SomeClass.dictionary['a']()

It will always use the dictionary defined in SomeClass.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top