6

How can I access the local variables of a super class method in an overridden method in the subclass?

class Foo(object):
    def foo_method(self):
        x = 3

class Bar(Foo):
    def foo_method(self):
        super().foo_method()
        print(x) # Is there a way to access x, besides making x an attribute of the class?

The code below gives a NameError: name 'x' is not defined

bar = Bar()
bar.foo_method()

This isn't surprising, and it can be fixed by making x an instance attribute, but can x be accessed as-is in Bar.foo_method more directly?

Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
Alejandro
  • 623
  • 6
  • 16
  • 3
    You can’t do that. Why do you need to? – Ry- Jul 26 '17 at 00:52
  • 1
    I don't need to do it. I just want to know if it's possible. Usually when a feature of Python is hard to find, then it means there is a better way to do it. – Alejandro Jul 26 '17 at 00:55
  • 1
    In theory, you _shouldn't_ know the internal workings of a class/method unless it specifically exposes those as public properties. – Selcuk Jul 26 '17 at 00:57

1 Answers1

6

Summary

Q. ... can x be accessed as-is in Bar.foo_method more directly?

As written, the answer is no.

By the time the super().foo_method() has returned, the stack frame for that method has been wrapped-up and the local variables are gone. There is nothing to access.

Alternative solution: return statement

The easiest solution to sharing the data is to have foo_method return x:

class Foo(object):
    def foo_method(self):
        x = 3
        return x

class Bar(Foo):
    def foo_method(self):
        x = super().foo_method()
        print(x)

Alternative solution: dynamic scoping

If you're looking for something akin to dynamic scoping, the easiest solution is to pass in a shared namespace:

class Foo(object):
    def foo_method(self, ns):
        x = 3
        ns['x'] = 3

class Bar(Foo):
    def foo_method(self):
        ns = {}
        super().foo_method(ns)
        x = ns['x']
        print(x)

If you want to simulate dynamic scoping in nested calls, consider using collections.ChainMap().

Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
  • I like the dynamic scoping edit. Since this only really matters when you can't change the signature and return type, then maybe ns should be an optional keyword argument, and add the `x` key only if it is not `None`. – Alejandro Jul 26 '17 at 01:16