[Python-Dev] PEP 8 updates/clarifications
Jim Fulton
jim at zope.com
Mon Dec 12 00:03:58 CET 2005
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()`` and
> ``obj.setFoo(v)``, instead just expose a public attribute (``obj.foo``).
> If necessary you can use ``property`` 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._MyPackage_variable 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
More information about the Python-Dev
mailing list