[Python-Dev] PEP 8 updates/clarifications (original) (raw)

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


skip at pobox.com wrote:

Jim> I don't understand this argument. Any mutating method or property Jim> invoked by foreign code changes an object's state.

Sure, but the only place I need to look for direct changes to the object's state are in the object's own code.

Jim> If you provide a property or a pair if accessors that just sets and Jim> gets an attribute with a slightly different name, that affords no Jim> more protection than if people were setting the attribute directly.

Sure it does. Suppose I get an exception in my code because some bit of code somewhere broke my assumptions about the values an attribute could assume. If that attribute is only set by the object's own code, I can more easily debug it (stick in a print or an assert in the places where the attribute changes, etc). If some external bit of code does something like self.foo = Foo() ... self.foo.attr = None then later in Foo's code I have something like self.attr.callme() The first thing I need to do is figure out who stomped on self.attr. That can be time-consuming if I don't necessarily know where the stomping occurred.

I just don't buy this argument. For trivial accessors and properties, you can't just look at your code to know where the changes are initiated. For debugging purposes, it's easy to add a property to allow debugging of attribute assignment.

At work we use Python for very rapid development of trading applications. Today I think we made about a half-dozen micro releases fixing bugs and our traders tried each one immediately live. Much of the design is carried around in our heads or consists of a few equations scribbled on sheets of paper. As you might imagine, it's a very lively environment. Localizing attribute modifications is a very good thing for us, even if they are simply one-line set methods.

Having to write accessors for all your public methods doesn't seem consistent with rapid development. It increases the ceremony of development and adds lots of meaningless boilerplate that readers of the code have to wade through. Note that they can't just skip over it, because they can't know if you've slipped something meaningful into one of these accessors.

Jim> If you don't want external code to change an attribute, don't Jim> expose it through a public API.

I suppose "public" is subject to some interpretation. Just because I don't prefix an attribute with an underscore doesn't mean I've implicitly declared it public. I assume that people will familiarize themselves with the callable methods of an object and only use direct attribute access if I haven't provided the necessary methods.

A better approach is to document the API for your classes and expect people to use that API. Prepending an underscore documents that a variable or method is internal. (Of course, there's still the subclassing API to deal with, if you need one, but that's a separate issue.)

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