Accessors in Python (getters and setters)

Gerhard Fiedler gelists at gmail.com
Thu Jul 20 07:29:36 EDT 2006


On 2006-07-20 04:15:33, Steve Holden wrote:

> mystilleef wrote:
> [...]
>> 
>> I don't know it's your code not mine.
>> 
>> class Robust(object):
>> 
>> 	def __init__(self):
>> 		# Arbitrarily changing this state to False will crash app or will
>> 		# corrupt the whole event system.
>> 		self.__is_active = True
>> 
>> 	def get_is_active(self):
>> 		return self.__is_active
>> 
>> 	buffer_is_active = property(get_is_active, doc="True if buffer is
>> editable")
>> 
> Let's ignore changes of state for the moment. The mystical difference 
> that makes read access via
> 
>    some_robust.buffer_is_active()
> 
> acceptable and
> 
>    some_robust.__is_active
> 
> somehow dangerous (ignoring the fact that name_mangling will take place) 
> is what?
> 
>> 	def monitor_events(self):
>> 		# Only methods of this class can change __is_active.
>> 		# Add code to change __is_active here.
>> 		return
>> 
> I'm sure nobody would argue that if close synchronization between 
> multiple attributes is required then write accessors are a bad idea. But 
> using them unnecessarily just makes your code heavier, slower and less 
> easy to maintain.

I'm not sure, but there's one thing that has a potential to be the real
issue: what's the common way to create a property that is read-write for
the implementation and "read-only" for the interface? It seems to me that
this is what mystilleef is trying to do.

I know that Python doesn't really provide access control. But so far I've
learned that a leading underscore says "I'm implementation, don't touch me
unless you know what you're doing". So I imagine that I browse through code
and look for leading underscores for non-local object attributes, to spot
troublespots. So I imagine that using such attributes as "read-only"
interface elements may not be a good idea, because then you not only have
to spot them in outside code, you always also have to check whether that's
a read or a write access (to know whether it's something potentially
dangerous or not). I also don't know how you could use the computed
attribute methods to do different things for access from the outside and
from the inside (of the object).

So... _is_active is considered implementation. Don't mess with me, it says.
But the users of the class need access to it: read access. Do you just say
"read access isn't changing anything, so just use _is_active"? The
disadvantage is that the outside code is sprinkled with accesses to
attributes with leading underscores, which I assume looks kind of scary. Or
do you rename _is_active to is_active, indicating that access to it is
indeed allowed? Then you would have to do something in the attribute
accessors to control the write access -- because that still isn't a good
idea. But I need want to be able to write to it from inside the class...
but how, if the attribute accessor is preventing that? Is there a local
override for that? I'm sure there is... but is it a common technique?

I may have not used the correct terminology for everything, but I think
it's possible to parse that :)

And maybe that helps putting this to rest and make everybody happy :)

Gerhard




More information about the Python-list mailing list