Skip to content Skip to sidebar Skip to footer

How To Do Encapsulation In Python?

What's wrong with this? From objective, and functional standpoints? import sys class EncapsulationClass(object): def __init__(self): self.privates = ['__dict__', 'privates'

Solution 1:

Python has encapsulation - you are using it in your class.

What it doesn't have is access control such as private and protected attributes. However, in Python, there is an attribute naming convention to denote private attributes by prefixing the attribute with one or two underscores, e.g:

self._a
self.__a 

A single underscore indicates to the user of a class that an attribute should be considered private to the class, and should not be accessed directly.

A double underscore indicates the same, however, Python will mangle the attribute name somewhat to attempt to hide it.

classC(object):
    def__init__(self):
        self.a = 123# OK to access directly
        self._a = 123# should be considered private
        self.__a = 123# considered private, name mangled>>> c = C()
>>> c.a
123>>> c._a
123>>> c.__a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'C'object has no attribute '__a'>>> c._C__a
123

You can see in the last example that the name was changed from __a to _C__a, although it is still accessible within the class as self.__a.

Solution 2:

Well, Python does not have encapsulation as a sort of "philosophical" decision, in the same way that we use duck typing a lot. Personally I don't see the point of using private or protected arguments in a Python code.

Speaking of your code, it seems to work fine with the following getters and setters:

defset_a(self, v):
    self.a = v

defget_a(self):
    returnself.a

if you make the following modification to your last line of __ getattribute __(self, name):

returnobject.__getattribute__(self, name)

However, you can use sort of a notion of variable-protecting, if you prefix your private variables with __, as mhawke mentioned. Plus, Daniel's comment points out a limitation of your list arguments. You could keep the protected "get/set" behaviour by adding "private" and "protected"in your private list.

Solution 3:

In Mark Lutz's book Learning Python, Fifth edition, he mentioned a way of simulating encapsulation of class level like this:

"""
Created on Sun Oct  4 10:16:30 2020
@author: Mark Lutz
A typical implementation of encapsulation in python,
to use, call:@private(‘var1’, ‘var2’...)
"""defprivate(*values):
    defdecorator(cls):
        classProxy:
            def__init__(self, *args, **kwargs):
                self.inst = cls(*args, **kwargs)
            def__call__(self, cls, *args, **kwargs):
                return self.inst
            def__getattr__(self, attr):
                if attr in values:
                    raise AttributeError("Private valueiables are not accessible!")
                else: returngetattr(self.inst, attr)
            def__setattr__(self, attr, val):
                # Allow access inside the classif attr == 'inst': self.__dict__[attr] = val
                elif attr in values:
                    raise AttributeError("Private valueiables are not accessible!")
                else: setattr(self.inst, attr, val)
            def__str__(self):
                return self.inst.__str__()
        return Proxy
    return decorator

this can be used for class-level encapsulation (e.g.limiting the access of a variable or method in a class).

For module-level encapsulation, however, the only way that I can think of is that you create a file and write the init.py. However if those who writes the client program knows the structure of your file / package, this can still not stop them from importing stuff.

Post a Comment for "How To Do Encapsulation In Python?"