Accessors in Python (getters and setters)

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Thu Jul 20 16:41:44 EDT 2006


Gerhard Fiedler a écrit :
> On 2006-07-20 09:40:31, Bruno Desthuilliers wrote:
> 
> 
>>>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? 
>>
>>class Foo(object):
>>  @apply
>>  def _imp():
>>    def fget(self):
>>      # code here
>>    def fset(self, val):
>>      # code here
>>    return property(**locals())
>>
>>  @apply
>>  def api():
>>    def fget(self):
>>      return self._imp
>>    def fset(self, val):
>>      raise SomeException('read-only, sorry')
>>    return property(**locals())
> 
> 
> Thanks a lot. This looks similar to what Steve Holden wrote. 

It's of course based on the same principle - which I bet is a very 
common pattern in Python[1]. The main difference with Steve's code is 
that I took your requirement almost to the letter: there are actually 2 
properties, one marked as implementation and read/write, the other 
public and read-only returning the value of the first one.


[1] could almost justify a PEP for a builtin ReadOnlyAttribute descriptor...

> (And yes,
> Steve, you understood exactly what I meant :)
> 
> My hunch is that this is what mystilleef might have wanted to say all
> along; it looks quite similar to what he seemed to try to express. It's
> basically the Python synonym of creating a public accessor (api) for a
> private attribute (_imp) --

It's probably the primary use case for properties. But it would be 
definitively useless to do so if what you want is read-write access.

> in this case to make the API read-only while
> maintaining the implementation read-write,

read-write but computed. The most common case (where the r/w 
implementation attribute needs no computation) is solved by Steve's example.

> but I'm sure there are other
> uses for such a structure. 
> 
> 
> 
>>Note that a read-only property named 'is_active' returning the value of
>>an attribute named '_is_active' doesn't prevent direct access to
>>'_is_active' attribute, neither from the class nor from the client code.
> 
> 
> Right; I already understood that :)
> 
> I just thought one part of this whole thread was that accessors are not
> necessary in Python.

they are not necessary for full read-write access to an existing attribute.

> However, it seems that this case -- different
> restrictions (or actions) for access from implementation vs through the API
> (which is probably one of the most common reasons for using accessors in
> other languages) -- in Python also can only be handled by adding a separate
> accessor. (This of course in Python is implemented as a computed
> attribute.)
> 
> The above illustrated technique doesn't look so different from a C++ or
> Java code with public set/getApi() accessors acting on a private imp
> attribute (or public set/getIsActive() accessors acting on a private
> isActive attribute -- to use the other, similar example that operates with
> the names this thread likes to use :)

The two mains differences are:
- no need to write the accessors if all they do is get/set a variable
- keep an attribute access syntax

Else, no, there's no fundamental difference.

> Do I seem to understand this correctly?

Looks like.




More information about the Python-list mailing list