How can I reach a private variable within the object
Asked Answered
M

3

5

I would like to modify an object private variable

class Example():
    __myTest1 = 1
    __myTest2 = 1
    def __init__(self):
        pass
    def modifyTest(self, name = 'Test1', value):
        setattr(self, '__my'+name, value);

I tried the code above and it's seems that not possible to reach a private variable,

AttributeError: Example instance has no attribute '__myTest1'

Is there any way to modify a private variable?

Macaluso answered 3/4, 2012 at 9:21 Comment(2)
Those aren't private variables. They are merely name-mangled. Do not use them for privacy, that's what a single underscore is for.Encephalo
You forget self in modifyTest. def modifyTest(self, name = 'Test1', value)Haughay
D
8

Accessing from outside:

e = Example()
e._Example__myTest1   # 1

Due to private variable name mangling rules.

But if you need to access private members, it is an indication of something wrong in your design.

If you need to access or update it from within the class itself:

class Example():
    __myTest1 = 1
    __myTest2 = 1
    def __init__(self):
        pass

    @classmethod
    def modifyTest(cls, value, name="Test1"):
        setattr(cls, '_%s__my%s' % (cls.__name__, name), value)

This must be done because it is a private class-static variable and not a private instance variable (in which case it would be straightforward)

Decoder answered 3/4, 2012 at 9:26 Comment(4)
I would like to access inside the class, not from outsideMacaluso
@iUngi If you are writing this class, then you are doing it wrong. In Python, name mangled attributes are a terrible idea 99.99% of the time. Why are you using them here? If you just want something that's only relevant to the internal function of your class, use a single underscore.Bivalve
@agf I just tested this code with a derived class; it seems to work. Can you tell me some code that would break it. ThanksDecoder
@PreetKukreti Interesting. I was wrong about how that worked. I though one of the points of name mangling was to avoid clashing with the namespaces of subclasses.Constriction
A
1

Try adding a single underscore and the class name to the beginning of the variable.

def modifyTest(name = 'Test1', value):
    setattr(self, '_Example__my' + name, value)
Ardenia answered 3/4, 2012 at 9:32 Comment(0)
G
0
class Example():
    __myTest1 = 1
    __myTest2 = 1
    def __init__(self):
        pass
    def modifyTest(self, name, value):
        setattr(self, '__my'+name, value)

Optional variables must come after mandatory variables.

Gerbil answered 3/4, 2012 at 9:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.