[Python-Dev] PEP 8 updates/clarifications (original) (raw)
Jim Fulton jim at zope.com
Mon Dec 12 00:03:58 CET 2005
- Previous message: [Python-Dev] Deprecate __ private (was Re: PEP 8 updates/clarifications)
- Next message: [Python-Dev] PEP 8 updates/clarifications
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Ian Bicking wrote:
Jim Fulton wrote:
Designing for inheritance
Always decide whether a class's methods and instance variables should be public or non-public. In general, never make data variables public unless you're implementing essentially a record. It's almost always preferrable to give a functional > interface to your class instead (and some Python 2.2 > developments will make this much nicer). > > Yes, Python 2.2 developments have made this better. Use of property() > should be suggested. This seems outdated. My impression, in part from time spent working with the Python Labs guys, is that it is fine to have public data sttributes even for non-"record" types. In fact, I would argue that any time you would be tempted to provide "getFoo()" and "setFoo(v)" for some "private attribute foo", it would be better to make it public. I certainly find "blah.foo" and "blah.foo = v" to be much better than "blah.getFoo()" and blah.setFoo(v)". Certainly, properties provide a safety belt. I would argue it this way: Python APIs can include attributes as well as methods. Exposure of an attribute need not constrain the implementation, thanks to properties. OTOH, I wouldn't bother with a property unless it's needed. So, getting back to the original paragraph, perhaps it could say: Decide whether a class's methods and instance variables should be public or non-public. Non-public methods and variables should start with an underscore. Do not use accessor methods, like
obj.getFoo()
andobj.setFoo(v)
, instead just expose a public attribute (obj.foo
). If necessary you can useproperty
to implement the same functionality that accessor methods would give you. If you do use properties, getting that property should never have a side effect. [well... I think that certain side effects like caching and logging are okay, but I'm not sure how to make that distinction] Potentially it could be added that the whole issue can often be avoided when an object's methods perform actions instead of returning attributes of the object. It's a long topic; maybe it could even just be a link, if someone knows of a good discussion along those lines. I'm sure there's some terminology here that I'm forgetting that describes the design pattern. There's also a point when the style guide becomes an API design guide, and I don't know how far it should go in that direction.
Perhaps something like:
"If you find yourself writing trivial accessor functions like:
def getFoo(self):
return self._foo
def setFoo(self, v):
self._foo = v
Use attribute accessors instead. In the example above, just store foo in an attribute named "foo". If you need to store foo a different way later, you can use properties.
On the other hand, if getting or setting a variable has other application- meaningful effects, then accessor methods might be better, or perhaps it would be best not to expose the attributes at all. "
...
While, on some level, private variables seem attractive, I think that experience (for everyone I know) has shown them to be an attractive nuisance. I recommend discouraging them.
I really really hate double underscores,
Doesn't everyone? :)
but I thought I'd let some other people suggest stronger language first. I prefer explicit name mangling for those cases where people justifiably use double underscores _now, e.g., self.MyPackagevariable instead of self.variable, which I think you also suggest below. Since it's all name mangling anyway, at least explicit is better than implicit, especially when it's something one could argue should look a little ugly. Perhaps all the non-public/private language should be switched to just "private" (one underscore) and "hidden from subclasses" (double underscore). I don't like calling _ private at all, because it's not what people coming from other languages think of as private.
I think we should strongly discourage it in the style guide. I think we should go even further, as I pointed out in another post.
I'll note that, IMO:
- If you have to worry about protecting attributes from subclasses, maybe should shouldn't be using inheritence. (This may be too bold a statement, but perhaps the first rule of inheritence should echo Fowler's first rule of Distribution: "don't inherit". :) Increasingly, I like to use inheritence only to avoid "boiler plate" implementations, such as default methods or data implementations that almost all implementations of some API are going to do the same way. On rare occasions, I find inheritence to be, sadly, unavoidable. I should also make a distinction between what I would call "private" and "public" inheritence. Private inheritence is between classes that are part of a single implementation unit or having a single implementor. With private inheritence, there is much less danger since the same people are responsible for the base classes and subclasses. It is public inheritence, where separate people maintain the base and subclasses where I think inhetitence should be used sparingly. Public inheritence causes too much coupling. ) I think this is getting more into design, and less style guide.
Yup. Although the style guide certianly touches design in places.
...
What about for class methods in particular; do you use class as the first argument for those methods?
It depends on the context. I prefer self, as, if it's a class method, it's clear (to me :) that self is a class. I sometimes use cls to be consistent with other code, but I don't like it.
Also, in the case of builtins, trailing 's are dangerous; unlike keywords you won't get a SyntaxError if you leave the off, or even a NameError.
Good point.
As I think about it, I should really change my own style to stop using even corruptions like lst, but perhaps seq instead. But that's wandering off in a different direction from keywords.
Yup.
Jim
-- Jim Fulton mailto:jim at zope.com Python Powered! CTO (540) 361-1714 http://www.python.org Zope Corporation http://www.zope.com http://www.zope.org
- Previous message: [Python-Dev] Deprecate __ private (was Re: PEP 8 updates/clarifications)
- Next message: [Python-Dev] PEP 8 updates/clarifications
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]