www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Need Help with Encapsulation in Python!

reply Soham Mukherjee <sohammm1087 gmail.com> writes:
```
    self.a = 1
     self.b = 2
     self.c = 3
     pass

   def __getattribute__(self, name):
     if sys._getframe(1).f_code.co_argcount == 0:
       if name in self.privates:
         raise Exception("Access to private attribute \"%s\" is 
not allowed" % name)
       else:
         return object.__getattribute__(self, name)
     else:
       return object.__getattribute__(self, name)

   def __setattr__(self, name, value):
     if sys._getframe(1).f_code.co_argcount == 0:
       if name in self.privates:
         raise Exception("Setting private attribute \"%s\" is not 
allowed" % name)
       elif name in self.protected:
         raise Exception("Setting protected attribute \"%s\" is 
not allowed" % name)
       else:
         return object.__setattr__(self, name, value)
     else:
       return object.__setattr__(self, name, value)


example = EncapsulationClass()


allowed

not allowed



attribute "b" is not allowed
```

What would actually be wrong with doing something like this?

Is there any better way to achieve encapsulation in Python? 
Please rectify my code if possible.
Jun 17 2022
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Friday, 17 June 2022 at 13:58:15 UTC, Soham Mukherjee wrote:
 Is there any better way to achieve encapsulation in Python? 
 Please rectify my code if possible.
One convention is to use "self._fieldname" for protected and "self.__fieldname" for private class attributes.
Jun 17 2022
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Friday, 17 June 2022 at 14:14:57 UTC, Ola Fosheim Grøstad 
wrote:
 On Friday, 17 June 2022 at 13:58:15 UTC, Soham Mukherjee wrote:
 Is there any better way to achieve encapsulation in Python? 
 Please rectify my code if possible.
One convention is to use "self._fieldname" for protected and "self.__fieldname" for private class attributes.
Example: ```python class A: def __init__(self): self._x = 3 self.__x = 4 a = A() print(a.__dict__) ``` will produce the output: ```{'_x': 3, '_A__x': 4}``` . As you can see the "self.__x" field has the name "_A__x" which makes it "hidden", but not inaccessible. But you can use external tools to check for misuse.
Jun 17 2022
prev sibling parent Soham Mukherjee <sohammm1087 gmail.com> writes:
[Here](https://www.scaler.com/topics/python/encapsulation-in-python/), they
mentioned a way of simulating encapsulation of class level like this:
```
def private(*values):
     def decorator(cls):
         class Proxy:
             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: return getattr(self.inst, attr)
             def __setattr__(self, attr, val):

                 if 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.
Jun 17 2022