ActiveState Code

Recipe 576677: Accessor function for private variables in Py3.x


Technique for accessing __var names.

Python
 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'))

Discussion

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.

Comments

  1. 1. At 10:28 p.m. on 20 aug 2009, Gabriel Genellina said:

    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'
    

Sign in to comment