unpythonic use of property()?

J Kenneth King james at agentultra.com
Mon Apr 20 11:29:19 EDT 2009


Carl Banks <pavlovevidence at gmail.com> writes:

> On Apr 17, 4:00 pm, Scott David Daniels <Scott.Dani... at Acm.Org> wrote:
>> Carl Banks wrote:
>> > On Apr 17, 10:21 am, J Kenneth King <ja... at agentultra.com> wrote:
>> >> Consider:
>>
>> >> code:
>> >> ------------------------------------------------------------------------
>>
>> >> class MyInterface(object):
>>
>> >>     def __get_id(self):
>> >>         return self.__id
>>
>> >>     id = property(fget=__get_id)
>>
>> >>     def __init__(self, id, foo):
>> >>         self.__id = id
>> >>         self.foo = foo
>>
>> >> class MyInterface2(object):
>>
>> >>     def __init__(self, id, foo):
>> >>         self._id = id
>> >>         self.foo = foo
>>
>> >>     @property
>> >>     def id(self):
>> >>         return self._id
>>
>> ...
>> >> I was recently informed that it was 'unpythonic' and have since been a
>> >> little confused by the term. I've heard it bandied about before but
>> >> never paid much attention. What is 'unpythonic'? What about this example
>> >> is unpythonic?
>>
>> > There are different reasons someone might have said it.
>> > ...
>> > Some people think attribute name-mangling is unpythonic.  It's true
>> > that people sometimes mistakenly treat it a solid information hiding
>> > mechanism, but I wouldn't call its usage unpythonic when used as
>> > intended: as a way to avoid name-collisions.  If you think it's
>> > worthwhile to protect an attribute from being overwritten, you might
>> > as well guard against accidental conflict with the underlying name.
>>
>> Here you are assuming that a user of your class could not possibly have a
>> valid reason for getting to the underlying variable.  Don't make those
>> decisions for someone else, in Python, "we are all adults here."
>
> They can use the demangled name of the internal variable if they want
> access to it.
>
>
>> > Finally, some people think read-only attributes are unpythonic.  I
>> > think that's ridiculous, although in general I'd advise against making
>> > attributes read-only willy-nilly.  But there's a time and place for
>> > it.
>>
>> Generally, properties are for doing some form of calculation, not
>> for making things read-only.
>
> That might be how properties are "generally" used, but if for some
> reason I wanted a read-only attribute, that's how I'd do it.
>
>
> [snip strawman stuff]
>> It is not
>> your job to protect those users who do not use your code properly from
>> themselves; that way lies madness.
>
> I'm sorry, but the universe is not as simple as you are making it out
> to be.  Blanket statements like the one you just gave here are not
> something that should ever be blindly adhered to.
>
> If, in my judgment, users would be prone to overwrite one of my
> attributes, and if I designed the system to rely on that attribute,
> and if the results of changing it are bad enough, then by golly I'm
> going to make the attribute harder than usual to modify.  And yes,
> that is my job.
>
> Users who want to change it anyway can curse me and then go demangle
> the name themselves.
>
>
> Carl Banks

Thanks for all the replies --

While greatly simplified, the reason for desiring read-only attributes
in this case is that the interface is to a remote server whose policy
relies on data objects represented by this class to have a few values
which never change or are managed by the server and not the end
user. Changing the ID value would break things on the server, so I
wanted to write the interface class to respect those conventions.

I'm well aware that if a developer really wanted to, they could get
around it no matter what I did, but I figure that if I at least make
it really difficult it will be obvious that they're really going into
dangerous territory.

Further (and this might just be a tad paranoid), user interface code
which might use this API might be dangerous. It's one thing for a
developer to break the rules when they need to, but a user shouldn't
be able to. By enforcing read-only on the API it ensure (at least in
my world view) that a developer writing a user interface against it
won't have to code defensively against malicious input.

However, since the difference between the two is simply attribute
name-mangling it's practically a pedantic issue. I guess there might
be some hyper-specific scenario where MyInterface would still be
useful, but this one might not be it.

Again, thanks. :)



More information about the Python-list mailing list