[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