Welcome, guest | Sign In | My Account | Store | Cart

Technique for accessing __var names.

Python, 21 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# Accessor function for private variables in Py3.x

def get_private_attr(inst, attr):
    'Access private variables without resorting to name mangling'
    s = ('class %(cls)s: \n' +
         ' def _show(self):  return self.%(attr)s \n' +
         'private = %(cls)s._show(inst) \n')
    s %= dict(cls=inst.__class__.__name__, attr=attr)
    d = dict(inst=inst)
    exec(s, d, d)
    return d['private']


if __name__ == '__main__':

    class MyClass:
        def __init__(self, x):
            self.__hidden = x

    m = MyClass(10)
    print(get_private_attr(m, '__hidden'))

Usually, private names are private for a reason. But, if you must get to them, here's a portable technique that doesn't rely on name mangling.

1 comment

Gabriel Genellina 14 years, 8 months ago  # | flag

Unfortunately it doesn't work when the attribute is declared in a base class.

class MyDerived(MyClass): pass

m = MyDerived(10)
print(get_private_attr(m, '__hidden'))

Traceback (most recent call last):
...
AttributeError: 'MyDerived' object has no attribute '_MyDerived__hidden'
Created by Raymond Hettinger on Tue, 3 Mar 2009 (MIT)
Python recipes (4591)
Raymond Hettinger's recipes (97)

Required Modules

  • (none specified)

Other Information and Tasks