[Python-Dev] PEP 8 updates/clarifications

Jim Fulton jim at zope.com
Tue Dec 13 13:26:25 CET 2005


Barry Warsaw wrote:
> On Sun, 2005-12-11 at 11:20 -0500, Jim Fulton wrote:
> 
> 
>>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.
> 
> 
> Let me know what you think about this language (from my in-progress
> update of PEP 8):
> 
>     Designing for inheritance
> 
>       Always decide whether a class's methods and instance variables
>       (collectively: "attributes") should be public or non-public.  Public
>       attributes are those that you expect unrelated clients of your class to
>       use, with your commitment to avoid backward incompatible changes.
>       Non-public attributes are those that are not intended to be used by
>       third parties; you make no guarantees that non-pubic attributes won't
>       change or even be removed.

I'd add somewhere: "If in doubt, chose non-public. You can always change your
mind later."

>       We don't use the term "private" here, since no attribute is really
>       private in Python (without a generally unnecessary amount of work).
>       However, another category of attribute are those which, while not being
>       public, are intended for use by subclasses (often called "protected" in
>       other languages).  Some classes are designed to be inherited from,
>       either to extend or modify aspects of the class's behavior.  When
>       designing such a class, take care to make explicit decisions about which
>       attributes are public, which are non-public but useful for subclasses, and
>       which are truly only to be used by your base class.

A useful term might be "subclass API".  Decide which non-public attributes
are part of the subclass API.

>       With this in mind, here are the Pythonic guidelines:
> 
>       - Public attributes should have no leading underscores.
> 
>       - If your public attribute name collides with a reserved keyword, append
>         a single trailing underscore to your attribute name.  This is
>         preferable to an abbreviation or corrupted spelling.  E.g. "class_"
>         is preferable to "cls" or "klass".
> 
>         Note 1: See the argument name recommendation above for class methods.
> 
> [BAW: I'll include this new text in a later followup]
> 
>       - For simple public data attributes, it is fine to expose just the
>         attribute name, without complicated accessor/mutator methods.  Keep in
>         mind that Python provides an easy path to future enhancement, should
>         you find that a simple data attribute needs to grow functional
>         behavior.  In that case, use properties to hide functional
>         implementation behind simple data attribute access syntax.
> 
>         Note 1: Properties only work on new-style classes.
> 
>         Note 2: Try to keep the functional behavior side-effect free, although
>         side-effects such as caching are generally fine.

Personally, I'd actively discourage use of trivial accessors.  Simple
attribute access is not only "fine", IMO, but it is much better than
trivial accessors.  This is an important point, IMO, because, in my
experience, the vast majority of accessors *are* trivial.

>       - If your class is intended to be subclassed, and you have attributes
>         that you do not want subclasses to use, consider naming them with
>         double leading underscores and no trailing underscores.  This invokes
>         Python's name mangling algorithm, where the name of the class is
>         mangled into the attribute name.  This helps avoid attribute name
>         collisions should subclasses inadvertently contain attributes with the
>         same name.
> 
>         Note 1: Note that only the simple class name is used in the mangled
>         name, so if a subclass chooses both the same class name and attribute
>         name, you can still get name collisions.
> 
>         Note 2: Name mangling can make certain uses, such as debugging, less
>         convenient.  However the name mangling algorithm is well documented
>         and easy to perform manually.

Of course, I disagree with this last one, but I've been overruled.

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