0

In a MATLAB code, I have a class that is defined with various properties blocks. Following is an example:

properties (GetAccess = public, SetAccess = private)
    c = 0.3;
    MACHINE_PRECISION = 1e-16;
end

I want to convert the class definition into its python version keeping the same access specifications for the attributes as in MATLAB, i.e. public, private or protected. Now, the one way of doing it is using underscores in front of the names. For example:

__c = 0.3
__MACHINE_PRECISION = 1e-16

Unfortunately, I need to keep the same names since these class definitions are used elsewhere and it's imperative to keep the same names. Is there any way of getting around this roadblock, i.e. specifying the access for the class attributes without having to change their names?

Pratik Dash
  • 81
  • 1
  • 10
  • 1
    `__name` **is not an access specifier*. Python *does not have access-specifiers*. *everything* is essentially public. There *is no public, private or protected.* By *convention* to mark a variable as part of the non-public API, you can use *a single underscore*. – juanpa.arrivillaga May 13 '20 at 00:02
  • Also: "Unfortunately, I need to keep the same names since these class definitions are used elsewhere and it's imperative to keep the same names. " That doesn't make much sense *for what is supposed to be a private attribute*. – juanpa.arrivillaga May 13 '20 at 00:03
  • The private attributes aren't needed in an instance variable or any subclass. To be more specific, inside the class definition I have public and private attributes. Private attributes are used in methods within the class definition and I don't want these attributes to be present in an object of the class. – Pratik Dash May 13 '20 at 00:11
  • **there are no private attributes because python doesn't support private variables** – juanpa.arrivillaga May 13 '20 at 00:14
  • 1
    "used in methods within the class definition and I don't want these attributes to be present in an object of the class": I don't think you can do that with python without black magic. You can't "specify the access for the class attribute", period. Names matter little. – Andras Deak -- Слава Україні May 13 '20 at 00:16
  • Looking at your example's `GetAccess = public, SetAccess = private`, are you perhaps looking for [properties](https://docs.python.org/3/library/functions.html#property)? – Andras Deak -- Слава Україні May 13 '20 at 00:21
  • @AndrasDeak almost certainly not. `property` doesn't give you access modifiers either. And I would hesistate to bring them up, because people coming from languages like Java will then procede to create pointless properties, defeating their entire purpose. – juanpa.arrivillaga May 13 '20 at 00:26
  • @AndrasDeak Does that mean I should have getter and setter methods for each variable? I have hundreds of variables in my class definition and it seems cumbersome to specify `property` for each variable. – Pratik Dash May 13 '20 at 00:37
  • @PratikDash **no never write getters and setters in Python**. If your all your`property` would do is merely get and set some attribute, **just use a plain attribute**, don't use a `property` – juanpa.arrivillaga May 13 '20 at 00:39
  • @juanpa.arrivillaga I see your point in the futility of using `property`. It's also not optimal for me to define a `property` for each private member. – Pratik Dash May 13 '20 at 00:50
  • @PratikDash it simply doesn't make sense, if you define a property for it, then it isn't really private – juanpa.arrivillaga May 13 '20 at 00:51
  • @juanpa.arrivillaga properties don't give you private attributes. But they do give you read-only attributes. Hence my question. – Andras Deak -- Слава Україні May 13 '20 at 00:59
  • @PratikDash to answer your question: no, you (almost) never write getters and setters in python, because attributes are accessible anyway. What I had in mind is something similar to the answer you got: using the `@property` decorator to expose a read-only attribute. It's not clear to me what you're really trying to do, so I don't know if this will help you. If you just want a nice java-y concept of encapsulation or whatever: well, you should reconsider. – Andras Deak -- Слава Україні May 13 '20 at 01:06
  • 1
    @AndrasDeak To be more specific, I did not want only read-only variables. I wanted private variables as well. I had just shown an example of a read only variable hoping to get some universal syntax for access modifiers in python similar to MATLAB or Java. But now I see that there is no such data encapsulation in python. – Pratik Dash May 13 '20 at 01:18
  • One thing that's more than just convention is name mangling which applies to attributes in a class definition with two leading underscores (assuming no trailing ones). These help with "private" attributes in inheritance. It won't help you here. – Andras Deak -- Слава Україні May 13 '20 at 01:21

1 Answers1

0

You could use properties to keep using the old names as getters:

class C:
    def __init__(self):
        self._c = 0.3
        self._MACHINE_PRECISION = 1e-16

    @property
    def c(self):
        return self._c

    @property
    def MACHINE_PRECISION(self):
        return self._MACHINE_PRECISION

Note that private class members in Python are prefixed by convention by an underscore (they are not really hidden by the interpreter, but it is a convention that followed by most Python code).

jerry
  • 499
  • 4
  • 10
  • **no you really shouldn't do this**. These `property`s serve no purpose. – juanpa.arrivillaga May 13 '20 at 00:39
  • The purpose of the properties is to allow accessing the fields by their original names. – jerry May 13 '20 at 00:40
  • **They are absolutely pointless** This gives you *nothing* over just a regular attribute, except a bunch of needless indirection. – juanpa.arrivillaga May 13 '20 at 00:43
  • @PratikDash these `property` objects serve no purpose. Don't do this. And for the last time **python doesn't have private members** – juanpa.arrivillaga May 13 '20 at 00:47
  • Python convention states that private variables should be prefixed by an underscore. It is even written in the docs. Therefore, you should not put a private variables without underscoring them and hence you must use properties to support legacy code that gets those variables. – jerry May 13 '20 at 00:47
  • @PratikDash no it is just a convention: https://docs.python.org/3/tutorial/classes.html – jerry May 13 '20 at 00:49
  • the op asked a readonly property, okey here it is, you can't set these properties, it is a read only, because you didn't define its `setter` – Mahmoud Elshahat May 13 '20 at 01:04
  • @jerry Your answer seems incorrect. It still allows access outside the class which shouldn't be the case with private members. Seems that it's not possible to have private access modifiers in python.. – Pratik Dash May 13 '20 at 01:09
  • @PratikDash , you posted this `properties (GetAccess = public, SetAccess = private)` which means a readonly from outside and can be set internally, is it right or i missed something???? – Mahmoud Elshahat May 13 '20 at 01:12
  • @Patrik Dash, you cannot change the properties, so I guess that by having access you mean access to the underscored variables. It *is* possible to have kind of private access in Python by using some hacks (you could forbid assignments to those fields by overriding `__setattr__` in an inherited class), however such code would be ugly and hard to understand and therefore people don't do it. Language convention states that private variables should simply be prefixed by an underscore and this convention is mostly followed by both library developers and library users. – jerry May 13 '20 at 01:17
  • @MahmoudElshahat you're right, In the example mentioned above I did specify the access to be read-only. But I meant to have some universal syntax for access modification as in java. To be specific, I am interested to have private variables with the same name as well which seems is impossible in python. – Pratik Dash May 13 '20 at 01:21
  • @jerry you can still bypass those hacks almost trivially, e.g. by using `object.__setattr__` or directly accessing the class namespace – juanpa.arrivillaga May 13 '20 at 01:22
  • @jerry You're right. It seems it's not possible to have private members without having an underscore in its name. – Pratik Dash May 13 '20 at 01:23
  • @juanpa.arrivillaga you could do equivalent things also in Java and many other languages that do have builtin access specifiers if you really insist to ignore them. – jerry May 13 '20 at 01:26
  • @jerry true, with enough gumption you can always bypass even language supported access modifiers. But it would require hacks at the bytecode level in Java... Much harder – juanpa.arrivillaga May 13 '20 at 01:28
  • @juanpa.arrivillaga I think in Java you could do this with reflection. – jerry May 13 '20 at 01:31
  • You can, although I believe this can be made more difficult with certain settings in the SecurityManager. But you are right, it's not even that hard most of the time – juanpa.arrivillaga May 13 '20 at 01:37