0

I just started programming in Python, and there's something OOP-related that I'm not quite clear on. So in Python, you can create and assign value to a new variable without needing to first declare it. So with that, is there any difference between creating and assigning a new variable for self (eg. self.variable = 5) inside a function (eg. __init__()) vs. creating and assigning a new private member variable? It seems to me like there is no difference at all.

class Foo:

    __var_A = 5;

    def __init__(self):
        self.__var_B = 5;
        self.printVars()

    def printVars(self):
        print(self.__var_A)
        print(self.__var_B)


foo = Foo()
3
  • 1
    There are no private variables in python. __var_A is going to be "mangled" to foo.__Foo_var_A if you are going to access that Commented Dec 12, 2016 at 14:11
  • 1
    It's _Foo__var_A, i.e. "_{classname}" prepended. Commented Dec 12, 2016 at 14:17
  • @filmor Oops, right. Anyways, documentation for reference - docs.python.org/3/tutorial/classes.html#private-variables Commented Dec 12, 2016 at 14:20

5 Answers 5

2

There is in fact a difference between those two variables:

Since __var_A is defined in class Foo instead of an individual member-function like __init__, you can change it for all instances at once like this:

Foo._Foo__var_A = 2

This will not work for __var_B since you define it individually per instance.

Note though, that changing __var_A on an instance will not change it for everyone else, it will instead put a local override into the object itself:

foo2 = Foo()
foo2._Foo__var_A = 1
Foo._Foo__var_A = 2
(foo2._Foo__var_A, foo._Foo__var_A) # Returns: (1, 2)
Sign up to request clarification or add additional context in comments.

1 Comment

I would also like to warn about using mutable objects as class variables.
2

It seems to me like there is no difference at all.

That is correct.

But remember that Python does not have 'private' members. That is only a convention.

6 Comments

There is a slight difference, though. varA is a class variable. varB is an instance variable
Yes, in the code. But the text of the question is asking about a situation ('assigning a new private member variable') that is different from the code.
What cricket_007 said, except (to be pedantic) they're attributes, not variables.
@PM2Ring ACK to that.
@PM2Ring Why attributes? docs.python.org/3/tutorial/…
|
1

The difference between protected and public is a matter of convention. And class or member variable prefixed by one _ indicates to a developer "don't use this unless you know what you're doing." Private is a SLIGHTLY different case, however: they require two _ and they cannot be suffixed by more than one _. Here are the docs:

“Private” instance variables that cannot be accessed except from inside an object don’t exist in Python. However, there is a convention that is followed by most Python code: a name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject to change without notice.

Name mangling is an important part of Python inheritence. It allows classes to protect API calls from accidental manipulation of descendants (see above docs). However, if necessary you can still access them via _<class-name><var name>. Eg:

class Foo:
   def __init__(self):
      self.__bar = 1

print(Foo()._Foo__bar)
# 1

Comments

0

There is no difference if the variable is declared under class foo: of within the __init__(self). Both methods accomplish the same thing.

However, this is slight a twist if the variable (e.g. self.bar) is declared from a method other than __init__. Using

def bar(self):
    self.bar = 'test'

creates a variable within the object that is not part of the default class. You can do this, but it is not good programming practice for python.

1 Comment

I agree that it's a good idea to create all instance attributes in __init__, but that doesn't mean that such attributes are "part of the default class". Technically, the attributes of the class itself are 1) those it inherits from its parent class(es), and 2) attributes defined at the class level. Instance attributes don't exist in the class itself, only in the instances of the class, and they only come into existence when the method creating them is executed, or when some code external to the class definition explicitly adds them.
0

There is a difference. Consider following example:

foo = Foo()
foo.__dict__

This will return:

{'_Foo__var_B': 5}

But, following code:

bar = Foo
bar.__dict__

will return

{'_Foo__var_A': 5,
 '__doc__': None,
 '__init__': <function __main__.__init__>,
 '__module__': '__main__',
 'printVars': <function __main__.printVars>}

This leads to conclusion that __var_A will be accessible even if Foo is not instantiated, while __var_B will not be.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.