787

I'm coming from the Java world and reading Bruce Eckels' Python 3 Patterns, Recipes and Idioms.

While reading about classes, it goes on to say that in Python there is no need to declare instance variables. You just use them in the constructor, and boom, they are there.

So for example:

class Simple:
    def __init__(self, s):
        print("inside the simple constructor")
        self.s = s

    def show(self):
        print(self.s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

If that’s true, then any object of class Simple can just change the value of variable s outside of the class.

For example:

if __name__ == "__main__":
    x = Simple("constructor argument")
    x.s = "test15" # this changes the value
    x.show()
    x.showMsg("A message")

In Java, we have been taught about public/private/protected variables. Those keywords make sense because at times you want variables in a class to which no one outside the class has access to.

Why is that not required in Python?

3

16 Answers 16

1193

It's cultural. In Python, you don't write to other classes' instance or class variables. In Java, nothing prevents you from doing the same if you really want to - after all, you can always edit the source of the class itself to achieve the same effect. Python drops that pretence of security and encourages programmers to be responsible. In practice, this works very nicely.

If you want to emulate private variables for some reason, you can always use the __ prefix from PEP 8. Python mangles the names of variables like __foo so that they're not easily visible to code outside the namespace that contains them (although you can get around it if you're determined enough, just like you can get around Java's protections if you work at it).

By the same convention, the _ prefix means _variable should be used internally in the class (or module) only, even if you're not technically prevented from accessing it from somewhere else. You don't play around with another class's variables that look like __foo or _bar.

49
  • 33
    That makes sense. However, I dont think there is any way in java to access private variables outside the class (except actually changing the source of the class ofcourse). Is there? Commented Oct 29, 2009 at 2:06
  • 236
    I tend to prefer the python way, but I don't think the java way is as pointless as you make out. Declaring something private quickly tells someone reading the code something very useful: this field is only ever modified inside this class.
    – Ned
    Commented Nov 13, 2009 at 9:24
  • 86
    @Omnipresent, you can using reflection.
    – rapadura
    Commented Mar 22, 2011 at 12:49
  • 157
    Let me get this straight, so Python does not implement public nor private attributes because "its a pretence of security and encourages programmers to be responsible", however the community encourages the use of "_" to denote private variables and methods? Maybe python should definetively have public and private no? Their main purpose is to tell you what API you should use to interact with a class. They serve as a documentation telling you to use these methods and not use those. They are not a "pretence of security", they are API documentation, which can even be used by the IDE to guide you!
    – PedroD
    Commented Oct 15, 2015 at 11:45
  • 68
    This is a good answer and your reasoning is certainly valid, but I disagree with one aspect. The purpose of access modifiers has never been security. Rather, they are a means of explicitly demarcating (and to a large degree, enforcing) what parts of a class are considered internal and which are exposed to outside users of that class. Conventions (culture) are certainly a valid alternative to access modifiers, and both methods have their pros and cons, but it is misleading to purpose that language-level access modifiers are intended in any way to be "secure" in the usual sense of the word.
    – devios1
    Commented Jan 4, 2017 at 18:43
267

Private variables in Python is more or less a hack: the interpreter intentionally renames the variable.

class A:
    def __init__(self):
        self.__var = 123
    def printVar(self):
        print self.__var

Now, if you try to access __var outside the class definition, it will fail:

>>> x = A()
>>> x.__var # this will return error: "A has no attribute __var"

>>> x.printVar() # this gives back 123

But you can easily get away with this:

>>> x.__dict__ # this will show everything that is contained in object x
               # which in this case is something like {'_A__var' : 123}

>>> x._A__var = 456 # you now know the masked name of private variables
>>> x.printVar() # this gives back 456

You probably know that methods in OOP are invoked like this: x.printVar() => A.printVar(x). If A.printVar() can access some field in x, this field can also be accessed outside A.printVar()... After all, functions are created for reusability, and there isn't any special power given to the statements inside.

12
  • 4
    in short, this is not encapsulation Commented Sep 26, 2015 at 22:11
  • 2
    I wonder if PHP has something similar with its goofy private variables - since private variables don't really make sense in interpreted language - I mean what optimization can it do knowing x variable is private, if it is not compiled?
    – NoBugs
    Commented Dec 24, 2015 at 5:14
  • 1
    How can we randomize the pattern of private variables?
    – crisron
    Commented Feb 7, 2016 at 5:29
  • 13
    @watashiSHUN "in short, this is not encapsulation" => yes it is. Encapsulation is about only using the public API so client code is protected from implementation changes. Naming conventions are a perfectly valid way to tell what is API and what is implementation, and the point is that it just works. Commented Apr 13, 2018 at 7:07
  • 2
    Encapsulation has nothing to do with whether or not you can access a private variable through convoluted methods. Anyone can access the memory directly in C++ which has "private variables". Python can also access "private variables". Big deal. Commented Oct 23, 2018 at 22:21
40

As correctly mentioned by many of the comments above, let's not forget the main goal of Access Modifiers: To help users of code understand what is supposed to change and what is supposed not to. When you see a private field you don't mess around with it. So it's mostly syntactic sugar which is easily achieved in Python by the _ and __.

3
  • 5
    I think this is as important a point as any. When debugging code (I know, I'm a weakling to introduce bugs), know which classes can change a member variable simplifies the debugging process. At least, if the variable is protected by some scope. A similar concept is const functions in C++. I know that member variables weren't changed in there and so I don't even look at that method as the potential cause of a bad variable setting. Although it can make subsequent development of class extensions/adding features, limiting the visibility of code makes it easier to debug.
    – MrMas
    Commented Nov 18, 2015 at 23:01
  • 1
    Is there any difference between single _ and double __ prefixes? Commented Apr 18, 2024 at 15:05
  • yes. I explain it in my answer: stackoverflow.com/a/51052134/7483073
    – Hatatister
    Commented Jan 31 at 16:18
35

Python does not have any private variables like C++ or Java does. You could access any member variable at any time if wanted, too. However, you don't need private variables in Python, because in Python it is not bad to expose your classes' member variables. If you have the need to encapsulate a member variable, you can do this by using "@property" later on without breaking existing client code.

In Python, the single underscore "_" is used to indicate that a method or variable is not considered as part of the public API of a class and that this part of the API could change between different versions. You can use these methods and variables, but your code could break, if you use a newer version of this class.

The double underscore "__" does not mean a "private variable". You use it to define variables which are "class local" and which can not be easily overridden by subclasses. It mangles the variables name.

For example:

class A(object):
    def __init__(self):
        self.__foobar = None # Will be automatically mangled to self._A__foobar

class B(A):
    def __init__(self):
        self.__foobar = 1 # Will be automatically mangled to self._B__foobar

self.__foobar's name is automatically mangled to self._A__foobar in class A. In class B it is mangled to self._B__foobar. So every subclass can define its own variable __foobar without overriding its parents variable(s). But nothing prevents you from accessing variables beginning with double underscores. However, name mangling prevents you from calling this variables /methods incidentally.

I strongly recommend you watch Raymond Hettinger's Python's class development toolkit from PyCon 2013, which gives a good example why and how you should use @property and "__"-instance variables (relevant section starts at 37min 16sec).

If you have exposed public variables and you have the need to encapsulate them, then you can use @property. Therefore you can start with the simplest solution possible. You can leave member variables public unless you have a concrete reason to not do so. Here is an example:

class Distance:
    def __init__(self, meter):
        self.meter = meter


d = Distance(1.0)
print(d.meter)
# prints 1.0

class Distance:
    def __init__(self, meter):
        # Customer request: Distances must be stored in millimeters.
        # Public available internals must be changed.
        # This would break client code in C++.
        # This is why you never expose public variables in C++ or Java.
        # However, this is Python.
        self.millimeter = meter * 1000

    # In Python we have @property to the rescue.
    @property
    def meter(self):
        return self.millimeter *0.001

    @meter.setter
    def meter(self, value):
        self.millimeter = value * 1000

d = Distance(1.0)
print(d.meter)
# prints 1.0
5
  • I'm going to check out that talk. Is the @property thing part of standard Python, or is it specific to an IDE? Commented Aug 20, 2019 at 6:23
  • Its part of the standard since python 2.6. If you should use an older version, there is still the possibility to use property builtin function, which is available since python 2.2
    – Hatatister
    Commented Aug 21, 2019 at 20:25
  • 1
    Sorry to mention this 4 years later, but it's bugging me . In your last example, when you're writting the setter, I think you wrote meter instead of value.
    – Daniel F.
    Commented Jul 19, 2022 at 23:27
  • You are right. I corrected the error.
    – Hatatister
    Commented Jul 20, 2022 at 6:32
  • 1
    This is the best answer. Java developers often forget what property and modules are for in Python.
    – Alex
    Commented Oct 26, 2022 at 8:48
18

There is a variation of private variables in the underscore convention.

In [5]: class Test(object):
   ...:     def __private_method(self):
   ...:         return "Boo"
   ...:     def public_method(self):
   ...:         return self.__private_method()
   ...:

In [6]: x = Test()

In [7]: x.public_method()
Out[7]: 'Boo'

In [8]: x.__private_method()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-fa17ce05d8bc> in <module>()
----> 1 x.__private_method()

AttributeError: 'Test' object has no attribute '__private_method'

There are some subtle differences, but for the sake of programming pattern ideological purity, it's good enough.

There are examples out there of @private decorators that more closely implement the concept, but your mileage may vary. Arguably, one could also write a class definition that uses meta.

5
  • 17
    I realize this is pretty late to the party but this link shows up on google when googling the issue. This doesn't tell the whole story. __x as a variable inside class A is actually rewritten by the compiler to _A__x, it's still not fully private and can still be accessed.
    – Zorf
    Commented Oct 13, 2014 at 23:20
  • 3
    Of course, if I see a variable named _A__x, I'm not going to touch it. It could be contagious. I'll run the hell away from it. Commented Jan 9, 2017 at 9:00
  • 2
    RIght sure its not a true private. But the principle reasoning for hard enforced private in C++ and Java (etc) , compiler optimisation, doesn't really exist in Python, so by-convention private is good enough. Python convention generally is that it trusts that you'll behave yourself without supervision. (And its a newbie trap, but you know, just be thoughtful about class design and consumption)
    – Shayne
    Commented Aug 20, 2019 at 7:08
  • @Shayne You cannot optimise in C++ based on access specifiers. You can access the private members of a class without resorting to C-style casts using just the header definition with some template tricks. See Johannes Schaub's answer to stackoverflow.com/questions/424104/…. Access specifiers really are only for you to protect you from yourself.
    – Chuu
    Commented Sep 13, 2021 at 16:07
  • 1
    You absolutely can. Private members can be optimized as straight relative JMP optcodes, whilst public members require vtables because they can be called externally. Yes work arounds exist, but they require that the access come from within the object.
    – Shayne
    Commented Sep 27, 2021 at 4:35
17

As mentioned earlier, you can indicate that a variable or method is private by prefixing it with an underscore. If you don't feel like this is enough, you can always use the property decorator. Here's an example:

class Foo:

    def __init__(self, bar):
        self._bar = bar

    @property
    def bar(self):
        """Getter for '_bar'."""
        return self._bar

This way, someone or something that references bar is actually referencing the return value of the bar function rather than the variable itself, and therefore it can be accessed but not changed. However, if someone really wanted to, they could simply use _bar and assign a new value to it. There is no surefire way to prevent someone from accessing variables and methods that you wish to hide, as has been said repeatedly. However, using property is the clearest message you can send that a variable is not to be edited. property can also be used for more complex getter/setter/deleter access paths, as explained here: https://docs.python.org/3/library/functions.html#property

1
  • Django also appreciate this. Commented Feb 9, 2019 at 12:19
14

Python has limited support for private identifiers, through a feature that automatically prepends the class name to any identifiers starting with two underscores. This is transparent to the programmer, for the most part, but the net effect is that any variables named this way can be used as private variables.

See here for more on that.

In general, Python's implementation of object orientation is a bit primitive compared to other languages. But I enjoy this, actually. It's a very conceptually simple implementation and fits well with the dynamic style of the language.

1
  • Yep. The beauty is, the metaprogramming abilities of python mean you can actually implement the fancy stuff if you want (And there are libraries that implement @private/@protected/etc decorators and stuff. Hell I even saw a library that imlemented JS style prototype classes for no goddamn sane reason) , but in practice its just not that necessary.. I kind of hate the "python/js/whatever is a lisp" meme because its almost never true, but python does share 'metaprogramming chops combined with simple syntax' with that language
    – Shayne
    Commented Aug 20, 2019 at 7:26
7

The only time I ever use private variables is when I need to do other things when writing to or reading from the variable and as such I need to force the use of a setter and/or getter.

Again this goes to culture, as already stated. I've been working on projects where reading and writing other classes variables was free-for-all. When one implementation became deprecated it took a lot longer to identify all code paths that used that function. When use of setters and getters was forced, a debug statement could easily be written to identify that the deprecated method had been called and the code path that calls it.

When you are on a project where anyone can write an extension, notifying users about deprecated methods that are to disappear in a few releases hence is vital to keep module breakage at a minimum upon upgrades.

So my answer is; if you and your colleagues maintain a simple code set then protecting class variables is not always necessary. If you are writing an extensible system then it becomes imperative when changes to the core is made that needs to be caught by all extensions using the code.

7

"In java, we have been taught about public/private/protected variables"

"Why is that not required in python?"

For the same reason, it's not required in Java.

You're free to use -- or not use private and protected.

As a Python and Java programmer, I've found that private and protected are very, very important design concepts. But as a practical matter, in tens of thousands of lines of Java and Python, I've never actually used private or protected.

Why not?

Here's my question "protected from whom?"

Other programmers on my team? They have the source. What does protected mean when they can change it?

Other programmers on other teams? They work for the same company. They can -- with a phone call -- get the source.

Clients? It's work-for-hire programming (generally). The clients (generally) own the code.

So, who -- precisely -- am I protecting it from?

37
  • 138
    -1: I agree with Porculus. It's not about forbidding access or hiding something, it's about implicit API documentation. Developers as well as compilers/interpreter/code-checker easily see which members are recommended to be used and which ones shouldn't get touched (or at least with care). In most cases it would be a horrible mess if all members of a class or module were public. Consider the distinction of private/protected/public members as a service, saying: "Hey, these members are important while those are used internally and probably not useful for you."
    – Oben Sonne
    Commented Oct 6, 2010 at 20:38
  • 25
    Late to the discussion, but everything Porculus and Oben are requesting here is handled perfectly adequately by the "prefix it with an underscore" convention (and without the harm that compiler enforcement of that convention can cause)
    – ncoghlan
    Commented Mar 2, 2011 at 15:16
  • 10
    @ncoghlan These points are made all over the internet and in Python publications galore. Doesn't make them scripture. Compiler enforcement of an interface, strong data encapsulation and typing are considered by many to be great benefits. "Privacy doesn't help make a design encapsulated." Agree to disagree. "Private is just ... to help folks who can't read the documentation or refuse to follow it." Again, silly. As we all can agree, there are benefits in both high level, loosely typed languages and low level, strongly typed languages. They are all tools in the toolbox!
    – Waylon
    Commented Feb 25, 2012 at 15:32
  • 43
    @S.Lott I'm not a python guy, so I won't comment from that perspective. However as a java developer this is truly horrifying advice. -1
    – dbyrne
    Commented Jun 6, 2014 at 14:24
  • 15
    Wow. You miss the point completely, you give a very bad piece of advice, you insult anyone who disagrees with you on this point, but you still get badges and more than 1000 reputation points for this "answer". Commented Jan 19, 2017 at 14:46
7

In Python 3, if you just want to "encapsulate" the class attributes, like in Java, you can just do the same thing like this:

class Simple:
    def __init__(self, str):
        print("inside the simple constructor")
        self.__s = str

    def show(self):
        print(self.__s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

To instantiate this do:

ss = Simple("lol")
ss.show()

Note that: print(ss.__s) will throw an error.

In practice, Python 3 will obfuscate the global attribute name. It is turning this like a "private" attribute, like in Java. The attribute's name is still global, but in an inaccessible way, like a private attribute in other languages.

But don't be afraid of it. It doesn't matter. It does the job too. ;)

2
  • 5
    this has existed since Python 1.5.2 IIRC, and it still doesn't prevent accessing the attribute through its mangled name. Commented Apr 13, 2018 at 6:27
  • 1
    The attribute name is not "global".
    – shivams
    Commented Feb 9, 2021 at 8:22
5

Private and protected concepts are very important. But Python is just a tool for prototyping and rapid development with restricted resources available for development, and that is why some of the protection levels are not so strictly followed in Python. You can use "__" in a class member. It works properly, but it does not look good enough. Each access to such field contains these characters.

Also, you can notice that the Python OOP concept is not perfect. Smalltalk or Ruby are much closer to a pure OOP concept. Even C# or Java are closer.

Python is a very good tool. But it is a simplified OOP language. Syntactically and conceptually simplified. The main goal of Python's existence is to bring to developers the possibility to write easy readable code with a high abstraction level in a very fast manner.

4
  • 3
    The rearson Private and Protected are important is that in statically compiled languages the compiler can create diirect calls to the private method, but must rely on a lookup table for public methods. Thiis simply isnt an issue with dynamic languages. Finally languages like C++ there are implications for inheritance and method resolution. Python and Ruby have very similar implementatiions of OO, so the comparison is meaningless. Smalltalk actually has no notion of public/private messages. Your free to add private as a category, but its purely advisory.
    – Shayne
    Commented Feb 24, 2017 at 5:21
  • To further my assertion. Frorm a codiing hygiene point of view, yes they are important for encapsulation, but its not necessary for it, and so the the @private (etc) decorators are more advisory than anything, but as private/public adds nothing useful to optimization in a non static language, its not implemented at a deep level like it would in a compiled language like java or c
    – Shayne
    Commented Feb 27, 2017 at 2:35
  • Encapsulation is a good cue. I think the main point is that private variables make inheritance from foreign classes safer. Otherwise you are risking collisions with internal attributes (i.e. you implicitly trust that none of your underscore-prefixed attribute names are used by the parent class, which is very wonky assumption).
    – mara004
    Commented Feb 7 at 22:49
  • See also docs.python.org/3/tutorial/classes.html#tut-private
    – mara004
    Commented Feb 7 at 22:51
1

Here's how I handle Python 3 class fields:

class MyClass:
    def __init__(self, public_read_variable, private_variable):
        self.public_read_variable_ = public_read_variable
        self.__private_variable = private_variable

I access the __private_variable with two underscores only inside MyClass methods.

I do read access of the public_read_variable_ with one underscore outside the class, but never modify the variable:

my_class = MyClass("public", "private")
print(my_class.public_read_variable_) # OK
my_class.public_read_variable_ = 'another value' # NOT OK, don't do that.
0

About sources (to change the access rights and thus bypass language encapsulation like Java or C++):

You don't always have the sources and even if you do, the sources are managed by a system that only allows certain programmers to access a source (in a professional context). Often, every programmer is responsible for certain classes and therefore knows what he can and cannot do. The source manager also locks the sources being modified and of course, manages the access rights of programmers.

So I trust more in software than in human, by experience. So convention is good, but multiple protections are better, like access management (real private variable) + sources management.

0

I have been thinking about private class attributes and methods (named members in further reading) since I have started to develop a package that I want to publish. The thought behind it were never to make it impossible to overwrite these members, but to have a warning for those who touch them. I came up with a few solutions that might help. The first solution is used in one of my favorite Python books, Fluent Python.


Upsides of technique 1:

  • It is unlikely to be overwritten by accident.
  • It is easily understood and implemented.
  • Its easier to handle than leading double underscore for instance attributes.

*In the book the hash-symbol was used, but you could use integer converted to strings as well. In Python it is forbidden to use klass.1

class Technique1:

    def __init__(self, name, value):
        setattr(self, f'private#{name}', value)
        setattr(self, f'1{name}', value)

Downsides of technique 1:

  • Methods are not easily protected with this technique though. It is possible.
  • Attribute lookups are just possible via getattr
  • Still no warning to the user

Another solution I came across was to write __setattr__. Pros:

  • It is easily implemented and understood
  • It works with methods
  • Lookup is not affected
  • The user gets a warning or error
class Demonstration:

    def __init__(self):
        self.a = 1

    def method(self):
        return None

    def __setattr__(self, name, value):
        if not getattr(self, name, None):
            super().__setattr__(name, value)
        else:
            raise ValueError(f'Already reserved name: {name}')

d = Demonstration()
#d.a = 2
d.method = None

Cons:

  • You can still overwrite the class
  • To have variables not just constants, you need to map allowed input.
  • Subclasses can still overwrite methods

To prevent subclasses from overwriting methods you can use __init_subclass__:

class Demonstration:
    __protected = ['method']

    def method(self):
        return None

    def __init_subclass__(cls):
        protected_methods = Demonstration.__protected
        subclass_methods = dir(cls)
        for i in protected_methods:
            p = getattr(Demonstration,i)
            j = getattr(cls, i)
            if not p is j:
                raise ValueError(f'Protected method "{i}" was touched')

You see, there are ways to protect your class members, but it isn't any guarantee that users don't overwrite them anyway. This should just give you some ideas. In the end, you could also use a meta class, but this might open up new dangers to encounter. The techniques used here are also very simple minded and you should definitely take a look at the documentation, you can find useful feature to this technique and customize them to your need.

0

Although there are not direct "private" variable conventions in python, you can certainly implement your own to varying degrees. In addition to prepended underscore or getter/setter methods, you can implement a truly private variable using Cython. Create the following files PriVar.pyx and setup.py with the follow contents respectively

# PriVar.pyx
cdef class PrivateVariable:
    cdef int _value
    def __cinit__(self):
        self._value = 0

    def getvalue(self):
        return self._value

    def setvalue(self, value):
        self._value = value

# setup.py
from setuptools import setup
from Cython.Build import cythonize

setup(ext_modules = cythonize('PriVar.pyx'))

Now build the module with the following command

 python3.10 setup.py build_ext --inplace

Now you can simulate "private" variables that are only accessible via the getter/setter functions.

Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> from PriVar import PrivateVariable
>>> myvar = PrivateVariable()
>>> dir(myvar)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'getvalue', 'setvalue']
  # try to get __dict__
>>> myvar.__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'PriVar.PrivateVariable' object has no attribute '__dict__'. Did you mean: '__dir__'?
  # can get and set, but not see
>>> myvar.getvalue()
0
>>> myvar.setvalue(42)
>>> myvar.getvalue()
42
>>> myvar.value
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'PriVar.PrivateVariable' object has no attribute 'value'

  # hmmm maybe its hidden?
>>> myvar._value
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'PriVar.PrivateVariable' object has no attribute '_value'
>>> myvar.__value
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'PriVar.PrivateVariable' object has no attribute '__value'. Did you mean: 'getvalue'?
  # definitely can not set a non existent attribute 
>>> myvar.value = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'PriVar.PrivateVariable' object has no attribute 'value'

  # lets try and override it with subclassing
>>> class NewPrivateVariable(PrivateVariable):
...     def __init__(self, v):
...         self.value = v
...

>>> mynewvar = NewPrivateVariable(100)
>>> mynewvar.value
100
>>> mynewvar.__dict__
{'value': 100}
>>> mynewvar.getvalue()
0
>>> mynewvar.setvalue(5)
>>> mynewvar.getvalue()
5
  # still can not access value associated with getter/setter function.. it's private!!

*edit the reason this works is Cython cdef int "variable" is created as private to the Cython modules scope. You can set public and readonly attributes as well. https://cython.readthedocs.io/en/latest/src/userguide/extension_types.html#static-attributes

-1

So I’m new to Python but I have a background in C# and JavaScript. Python feels like a mix of the two in terms of features. JavaScript also struggles in this area and the way around it here, is to create a closure. This prevents access to data you don’t want to expose by returning a different object.

def print_msg(msg):
    # This is the outer enclosing function

    def printer():
        # This is the nested function
        print(msg)

    return printer  # returns the nested function


# Now let's try calling this function.
# Output: Hello
another = print_msg("Hello")
another()

https://www.programiz.com/python-programming/closure

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#emulating_private_methods_with_closures

2
  • 3
    I'm not sure how this relates to the question... It is about private attributes in a class, not closure in functions...
    – Tomerikoo
    Commented Dec 27, 2021 at 9:35
  • 4
    Don't do this in Python. In Python, you simply use a leading underscore to signal that an attribute is "private", there are no access modifiers. Don't replace your classes with closures. Commented Dec 27, 2021 at 9:42

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.