27

If 'explicit is better than implicit', why aren't there explicit access modifiers in Python: Public, Protected, Private, etc.?

I know that the idea is that the programmer should know what to do through a hint - no need to use 'brute force'. But IMO 'Encapsulation' or 'information hiding' isn't just to keep people out, it's a question of organization and structure: your development layers should have self-defining, clearly delimited scopes and borders, just like physical systems do.

Can someone please help me out here with a solid explanation as to why access restrictions are implied rather than explicit in Python, a language that otherwise seems close to perfect?

Edit: So far I have seen 3 proposed answers, and I realized that there are 2 parts to my question:

  1. Why aren't there key words, for example

    private def myFunc(): 
        dostuff....
    

    instead of IMO the ugly and hard to type underscores. But that's not the important point.

  2. More importantly:

    Why are these access modifiers only 'recommendations' or hints and not enforced. It will be hard to change later? It's very simple to change 'protected' to 'public' - and if you have a convoluted inheritance chain that makes it difficult, you have a poor design - your design should be refined rather than relying on a language feature that makes it easy to write poorly structured code.

    When access modifiers are enforced, your code is automatically compartmentalized - you KNOW that certain segments are out of scope so you don't have to deal with them except if and when it's necessary. And, if your design is no good and you find yourself constantly moving things into and out of different scopes, the language can help you to clean up your act.

As much as I love Python, I'm finding this 2nd point to be a serious deficiency. And I have yet to see a good answer for this.

7
  • possible duplicate of Access specifiers in Python:... which was closed as not being constructive. Commented Jul 11, 2011 at 8:09
  • 2
    @Frank this is a re-ask of that question to attempt to be more constructive. I've gone ahead and deleted the original question.
    – user8
    Commented Jul 11, 2011 at 9:45
  • @Mark Trapp: Ah OK. Thanks for the clarification. I can't see how to rescind my vote-to-close. Commented Jul 11, 2011 at 10:13
  • @Frank It will age away on its own.
    – Adam Lear
    Commented Jul 11, 2011 at 12:53
  • the problem with private def whatever is, that class x: def whatever(self): pass is a shortcut for class x: pass; x.whatever = lambda self: pass, so basically, you would need a private modificator for assignment
    – keppla
    Commented Jul 12, 2011 at 6:23

4 Answers 4

22

"Explicit is better than implicit" is only one of the maxims in Python's design philosophy. "Simple is better than complex" is there too. And, although it's not in the Zen of Python, "We're all consenting adults here" is another.

That second rule is perhaps the most important here. When I design a class, I have some idea of how it's going to be used. But I can't possibly predict all possible uses. It may be that some future use of my code requires access to the variables I've thought of as private. Why should I make it hard - or even impossible - to access these, if a future programmer (or even a future me) needs them? The best thing to do is to mark them with a warning - as Joonas notes, a single underscore prefix is the standard - that they are internal, and might change; but forbidding access altogether seems unnecessary.

7
  • 1
    "Simple is better than complex" and "We're all consenting adults here" are why Smalltalk doesn't have access modifiers. Putting a method in the "private" category is a hint that you should think thrice before using it, and no more. Commented Jul 11, 2011 at 17:38
  • @Frank: "Putting a method in the "private" category is a hint that you should think thrice before using it, and no more" To me, it simply means I don't have to worry about it when I'm not dealing with it.
    – Vector
    Commented Jul 11, 2011 at 18:45
  • 11
    There is a good reason why forbid access to private members: because it may break class invariants. If you can't write private members, then you can't be sure your class behaves correctly.
    – svick
    Commented May 5, 2012 at 10:32
  • 11
    "Why should I make it hard - or even impossible - to access these, if a future programmer (or even a future me) needs them?" Because one of the basic principle of design is the separation between interface (what a piece of code provides) and implementation (how it provides it). Encapsulation serves to reduce the complexity of the code by reducing the dependencies between different parts of the code. So, public and private are used exactly for the purpose of keeping the code simpler by allowing to see only what is needed.
    – Giorgio
    Commented May 5, 2012 at 18:04
  • 5
    Cannot diagree more. Access modifiers promote two of probably the best understood concepts to curtail complexity in big software: Encapsulation and Separation of Concerns. Failing to serve neither of the two simply means python is not a good OOP language nor suitable to building big software and there is nothing wrong with that. But justifiying the absence of such features with typical hobbyist arguments like "Why add complexity when it's not needed?" is just wrong. Commented May 10, 2016 at 8:34
10

I would suspect the main reason for the missing access modificators is Simplicity

As you say, it's not about keeping people out, its about organisation, so the main point of 'private' is, that it sends a message to the users of your api 'please dont write code that depends on this'.

It's trivial to say 'by convention, _x or __x should not be used outside the class', but in python's dynamic object model, it would be hard to even come up with a notation.

class ActiveRow(object):
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)

how to note the accessability?

I guess, this was a trade off. If you strictly cannot live with it, I would suggest ruby, which has a similar level of abstraction and dynamicity, but has an object model, that allows for access modification.

6
  • 8
    I think this is correct, but IMO, it's terrible. For a language that uses elegance and readability as selling points writing __method__ is pretty heinous-looking and obtuse.
    – jiggy
    Commented Jul 11, 2011 at 16:21
  • 3
    thats not the convention, __x__ are 'magic', (i.e. methods that get called for enabling language integration like operator overloading, iterability, etc.). The convention is _x.
    – keppla
    Commented Jul 11, 2011 at 17:21
  • 6
    Sorry, I'm still getting my head around Python. I'm trying so hard to like it, but stuff like this drives a little batty. Especially now that I need to remember the meaning of how many underscores a method has. To OP's point, it seems that explicit modifiers would be more clear. Concision is great, but it can't trump clarity. You spend 10X more effort maintaining code than building it.
    – jiggy
    Commented Jul 11, 2011 at 18:19
  • 2
    My example wasnt meant to show different counts of underscores, the use of __init__ was incidental. The example sets some properties of the object, that are not know on compile time, so an explicit access modifier would not help you.
    – keppla
    Commented May 7, 2012 at 14:00
  • 7
    @jiggy: "I'm trying so hard to like it". I tried for 2 years - then gave up. :-( Appears to be a scripting language that was hacked to behave somewhat like a real OOP language. I can't imagine writing a large, complex app in Python that was well designed and readable. As you said 'You spend 10X more effort maintaining code than building it'. Simple OOP and type safe concepts require crazy hacks and workarounds.
    – Vector
    Commented May 3, 2013 at 17:26
9

The Python convention is to use an underscore prefix for protected/private members.

This convention, when followed, is effectively same as access modifiers, except 1) you'll see directly from the member's name whether it's public or not, and 2) you can break "encapsulation" if you really want to (this can be justifiable in e.g. testing; in some other languages you would have to use reflection == more code).

Ultimately it's a question of taste, but if you can do the same thing (with a bit more flexibility) without special keywords, the language will be smaller and code will be more concise, which is generally a good thing.

1
  • 2
    " if you can do the same thing (with a bit more flexibility) without special keywords, the language will be smaller and code will be more concise" In my opinion, this is generally not true. (Even if it can be true with the special case of access modifiers)
    – BenjaminB
    Commented Jul 11, 2011 at 14:28
0

It's probably because Python code tend to fragment into tons of small modules. So when a package is loaded, it can choose what to make available to the user.

Of course, this doesn't completely justify the lack of access modifiers, but it does decrease the chance of making mistakes.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.