Accessors in Python (getters and setters)

Gerhard Fiedler gelists at gmail.com
Sat Jul 15 09:32:31 EDT 2006


On 2006-07-15 06:55:14, mystilleef wrote:

> In very well designed systems, the state of an object should only be
> changed by the object. 

IMO that's not quite true. Ultimately, the state always gets changed by
something else (user interaction, physical events); very few objects are
completely self-contained in their behavior.

In most systems (and you possibly have written some of them) are objects
whose state gets changed by other objects -- possibly through the
intermediation of setter methods that do nothing else but set the state.
There's no conceptual difference between directly setting the state or
calling a setter function that does nothing else but directly setting the
state -- except for one unnecessary level of indirection in the latter.

> For example, a third party randomly changing is_active, (which Python
> lets you do freely and easily) from False to True may crash your GUI.
> And I'm not making this up. Things like this do really happen depending
> on the whackyness of your toolkit. 

That's quite true, but a setter that does nothing but change is_active
doesn't prevent this. If there is logic necessary to prevent state changes
in certain situations, this should be implemented. But whether you then
call this a part of the "behavior" (looking at the implementation as being
a setter method) or a part of the "state" (looking at the implementation as
being an added feature of the attribute) doesn't really make an objective
difference.

> So sometimes, it is my duty to protect the state of an object. 

Of course.

> Which is programming objects based almost entirely on state and behavior.
> As you can see this has nothing to do with Python vs Java's vs X's
> implementation of accessors and how using them sucks, or how they aren't
> Pythonic. Some domains just require this stuff.

Yes, but you seem to still be stuck in the paradigm that setting the state
is behavior if it comes from the outside -- probably because some languages
implement that way. 

I'm not (yet) a Python programmer. To be honest, the one single feature
that attracted me to Python is the structuring by indenting... I never
understood why we have to indent (to be able to read) /and/ brace (to make
the compiler happy) in other languages -- I always thought that if
indenting helps me to understand the structure, the compiler should be able
to read exactly that :)

I come from a mostly C/C++/Java/PHP background, apparently similar to
yours. GUI, embedded, whatever. But I can understand that the difference
you are making is not based in a concept, it is based in an implementation.

It is an artificial difference to say that 

  o.is_active = true

is modifying state, whereas

  o.set_active( true )

is dealing with behavior. Either way you are changing the state. Behavior,
that is, doing something, implies state change, one way or another,
sometimes relevant, sometimes not. There are (often embedded) systems, and
well-designed ones, that basically don't deal with what you call behavior
at all and handle everything through state change (of signals). Such
systems can be rock-solid and quite complex, and have a lot of "behavior".
And there are systems that do everything through what you call behavior
(e.g. getter/setter type implementations). Both types can work, both can
achieve the exactly same; this is just an implementation detail. 

> And this is why many overzealous OO languages do "force" you to use
> accessors. 

I'm not sure why you keep on harping on this. It seems to have been clearly
stated that in Python, every attribute /is/ an implied getter/setter pair
-- it's up to you to just let the language use the default (simple)
implementation, or override it with your own logic. It is also up to you to
call this added logic then a feature of "behavior" or of "state".

> Thinking in terms of state and behavior is, because it works regardless
> of programming language or implementations. 

Agreed. But the distinction is not universal, objective, it is subjective.
Where you make it is your choice. As the examples above show, there are
well-working solid systems out there that work on both ends of your
spectrum: only behavior is exposed, or only state is exposed. Both can
achieve the same. It is a subjective choice to call this 

  o.is_active = true
  
state or behavior... the underlying setter implementation for is_active can
do everything you want your behavior to be -- or it can be the simple
straightforward default setter. It's just a subjective thing to say that
this is in the realm of behavior or of state. Didn't you say that state
changes can crash a system? That's behavior, as far as I am concerned :)
And there is little if any behavior that doesn't change the state --
especially setters are known to do that :)

Gerhard




More information about the Python-list mailing list