-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should private or protected methods be preferred? #5
Comments
I am strongly in favour of composition over inheritance. The upshot of that is that I don't really see a place for inheritance (apart from pure-virtual / interface inheritance). If you follow that, there's not really a role for "protected" methods. Another reason people use them is because they want to be able to test those methods. I also don't believe in testing private methods (or methods that would be private if they weren't exposed for testing purposes). I consider it a code smell. If the full implementation of a class cannot be exercised via its public methods you probably need to extract some helper methods or some other classes. In terms of "not an obvious reason why someone should not be able to" override a method, keep in mind that (1) they can not only override it but also invoke it and (2) if you don't consider it part of the API you are unlikely to have thought about all the ways that it could be invoked or how a user might override it and whether your code is resilient to all of them. In summary, you should assume that things will break if someone invokes/overrides it. There's a cost to allowing it to be part of your API surface. With all of that in mind, I am in favour of double-underscores for any method or property that is not part of the public API of a class. |
CC @honkfestival on these discussions too |
💯 |
This is an argumentation in favor of using single underscore for declaring internal 1. PEP8 specify exactly this:
2. The world warns us not to use name mangling to emulate private attributes
https://www.python.org/dev/peps/pep-0008/#method-names-and-instance-variables
https://en.wikipedia.org/wiki/Name_mangling#Python Or https://softwareengineering.stackexchange.com/a/229807 3. This is the Python cultureThis whole stackoverflow response is great: http://stackoverflow.com/a/7456865
4. Google also has a large codebase and still doesn't require itThe Google Python style guide is a great addition to PEP8. 5. We should code in Python rather than MyCompanyPythonBasing the Shopify Python Style on Google Python style guide is the best thing to do. It means:
|
Python is evolving to meet the needs of more sophisticated codebases. Type annotations are a great example of this. Our objective in establishing a style guide is to innovate on the way Python is written at Shopify. While consistency with external practices is a good place to start, adherence to those practices should not override forward progress. Nor should a founding-fathers argument that the language should be used exactly as it was originally intended. Double-underscores force developers to think about how to design their classes to be both well factored / encapsulated and well tested. It's a useful mechanism, and the best available mechanism, for implementing a concept that is demonstrably useful in large codebases. With regards to Google and their own style:
In order to have a fruitful discussion about a particular style guideline, let's discuss how it might be helpful or harmful in a Shopify-specific context. |
Note: Shopify's python standards are almost completely, with only a few exceptions, the Google python standard. We explicitly incorporate them by reference, and have implemented several custom pylint rules to catch some of them. On the single/double underscore question, I have found double-underscores useful in designing good classes, thinking consciously about what should be inheritable/overridable. I find them inconvenient when debugging. In simple cases, where a class is not going to be inherited, there doesn't seem to be any advantage in going with double-underscores. |
That was my intent, I guess my comment was too long... Following best practices, like jumping on type-hinting is clearly must-do. Google has apparently only one internal amendment to the "Naming" section, which discourage using name mangling. What you want exists, it's the simple underscore, and the tooling to enforce this is already here: ************* Module poi.__main__
W: 4, 6: Access to a protected member _internal of a client class (protected-access) |
When defining class methods, we can hint that a function is protected by prefacing it with
_
or we can invoke name-mangling by prefacing it with__
. When there isn't an obvious reason why someone would want to override a method but there's also not an obvious reason why someone should not be able to, which should be our default?For a more specific example, see here.
@erikwright @JasonMWhite
The text was updated successfully, but these errors were encountered: