Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Declarative properties

Reply
Thread Tools

Declarative properties

 
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      10-08-2007
Dan Stromberg a écrit :
> On Fri, 12 Oct 2007 09:42:28 +0200, Bruno Desthuilliers wrote:
>
>
>>>>So what? Otherwise you carry *always* the baggage of a public
>>>>property and a private attribute whether you need this or not. At
>>>>least for me it would be unnecessary in most cases.
>>>
>>>That "baggage" of carrying around "unneeded" methods is something the
>>>computer carries for you - IE, no big deal in 99.99% of all cases.

>>
>>1/ Accessing the value of a property is not free. Accessing a plain
>>attribute is much cheaper.

>
>
> Python's current performance characteristics have no bearing on what is
> good software engineering practice in general,


Neither useless complexity nor tryig to apply inappropriate idioms are
good practices.

(snip)

> I'm not omniscient, and neither is anyone else; when one initially codes a
> class, one doesn't know to what purposes it will need to be bent in the
> future; using accessor methods instead of exposed attributes is
> significantly more flexible for the future of your class.


Please remember that Python has support for computed attributes (you do
know what's a computed attribute, don't you ?), so you can turn a plain
attribute into a computed one at any time without breakink the API. IOW,
you don't need getters/setter a priori.
 
Reply With Quote
 
 
 
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      10-08-2007
Dan Stromberg a écrit :
(snip)
> My implementation may or may not be lacking (feel free to improve it - in
> fact, please do!),


Since you ask for it:

def makeprop(name):
_name = '_' + name
def fget(self):
return getattr(self, _name, None)
def fset(self, val):
setattr(self, _name, val)
return property(fget, fset)

class AutoPropType(type):
def __init__(cls, clsname, bases, attribs):
for name in cls._autoprops:
if name not in attribs:
setattr(cls, name, makeprop(name))

class Demo(object):
__metaclass__ = AutoPropType
_autoprops = ('foo', 'bar', 'baaz')

def __init__(self, foo, bar=42, baaz='ni'):
self.foo = foo
self.bar = bar
self.baaz = baaz

d = Demo('yadda yadda')


> but that's irrelevant to the heart of the matter, which
> is "what you didn't think to plan for now most definitely can hurt you
> later".


Ahem... Please let me know, Mr Professor, what difference it would make,
from client code's POV, if we simply wrote this instead:

class Demo(object):
def __init__(self, foo, bar=42, baaz='ni'):
self.foo = foo
self.bar = bar
self.baaz = baaz


(snip more blah)

> Little hackish tricks for performance's sake scattered throughout a
> program are very wasteful of something more precious than CPU time.


Indeed. The point you're missing is that, in a language that supports
computed attributes, using plain attributes when that's all you need is
*not* a 'litlle hackish trick'. It's just common sense - and actually
saves on *both* programmer's and CPU time.
 
Reply With Quote
 
 
 
 
Artur Siekielski
Guest
Posts: n/a
 
      10-11-2007
Hi.

I would like to have declarative properties in Python, ie. something
like slots definitions in defclass in Common Lisp. It seems that even
Java will have it, using a library ( https://bean-properties.dev.java.net/
).

I know about 'property' function in Python, but it's normal usage
isn't declarative, because I have to code imperatively getters and
setters:

class Person(object):
def __init__(self, name):
self._name = name
def _get_name(self):
return self._name
def _set_name(self, new_name):
self._name = new_name
name = property(_get_name, _set_name)

I would like to have something like that:

class Person(object):
name = property('_name')

I assume that this causes "generation" of instance field '_name' and
default getters and setters. And if I would like to customize (g|
s)etters, I would write them by hand, or, better, use more declarative
approach (like @NotNull annotations in Java version).

I could probably code a solution to my problem with help of wonderful
introspection functionalities. But I'm looking for a standard and/or
proven way of doing this. Maybe some PEP is being prepared for this?

Regards,
Artur

 
Reply With Quote
 
Marc 'BlackJack' Rintsch
Guest
Posts: n/a
 
      10-11-2007
On Thu, 11 Oct 2007 11:48:18 +0000, Artur Siekielski wrote:

> class Person(object):
> def __init__(self, name):
> self._name = name
> def _get_name(self):
> return self._name
> def _set_name(self, new_name):
> self._name = new_name
> name = property(_get_name, _set_name)


This is more easily spelled:

class Person(object):
def __init__(self, name):
self.name = name

> I would like to have something like that:
>
> class Person(object):
> name = property('_name')
>
> I assume that this causes "generation" of instance field '_name' and
> default getters and setters.


But why? Default getters and setters are unnecessary and if you need
something other than the default you need to write it anyway more
explicitly.

Ciao,
Marc 'BlackJack' Rintsch
 
Reply With Quote
 
Artur Siekielski
Guest
Posts: n/a
 
      10-11-2007
On Oct 11, 2:27 pm, Marc 'BlackJack' Rintsch <(E-Mail Removed)> wrote:
> But why? Default getters and setters are unnecessary and if you need
> something other than the default you need to write it anyway more
> explicitly.


I see some problems with your approach:

1. If I use instance field 'name' which is accessed directly by other
classes,
and later I decide to implement nonstandard getter, I must refactor
'Person' class
and in some places change 'name' to '_name' (assuming this is now the
field's name).
The problem is that I cannot automatically change 'name' to '_name'
everywhere, because
in some places I want public property value (eg. validated and
formatted), and in other
places raw property value.

2. Properties define (a part of) public interface of a class. When
using fields for public
access, you must tell this explicitly in documentation, or use name
convention. And public
fields definition is mixed with private fields, which doesn't happen
when using properties.

3. Using properties as first-class objects gives possibilities to use
declarative approaches
for constructing them.

 
Reply With Quote
 
Marc 'BlackJack' Rintsch
Guest
Posts: n/a
 
      10-11-2007
On Thu, 11 Oct 2007 13:04:53 +0000, Artur Siekielski wrote:

> On Oct 11, 2:27 pm, Marc 'BlackJack' Rintsch <(E-Mail Removed)> wrote:
>> But why? Default getters and setters are unnecessary and if you need
>> something other than the default you need to write it anyway more
>> explicitly.

>
> I see some problems with your approach:
>
> 1. If I use instance field 'name' which is accessed directly by other
> classes,
> and later I decide to implement nonstandard getter, I must refactor
> 'Person' class
> and in some places change 'name' to '_name' (assuming this is now the
> field's name).
> The problem is that I cannot automatically change 'name' to '_name'
> everywhere, because
> in some places I want public property value (eg. validated and
> formatted), and in other
> places raw property value.


So what? Otherwise you carry *always* the baggage of a public property
and a private attribute whether you need this or not. At least for me it
would be unnecessary in most cases.

> 2. Properties define (a part of) public interface of a class. When
> using fields for public
> access, you must tell this explicitly in documentation, or use name
> convention. And public
> fields definition is mixed with private fields, which doesn't happen
> when using properties.


Attributes are public unless you start the name with an underscore which is
by convention a warning to not use that attribute unless you know what you
are doing. With properties all over the place you use that convention
anyway because the "real" value for `name` is bound as `_name`. So you
clutter your API with two attributes for non-method-attributes.

And a property is not automatically part of the public API, just if the
name does not start with an underscore.

> 3. Using properties as first-class objects gives possibilities to use
> declarative approaches for constructing them.


No idea what you mean here. Everything in Python is an object.

Ciao,
Marc 'BlackJack' Rintsch
 
Reply With Quote
 
sjdevnull@yahoo.com
Guest
Posts: n/a
 
      10-11-2007
Artur Siekielski wrote:
> On Oct 11, 2:27 pm, Marc 'BlackJack' Rintsch <(E-Mail Removed)> wrote:
> > But why? Default getters and setters are unnecessary and if you need
> > something other than the default you need to write it anyway more
> > explicitly.

>
> I see some problems with your approach:
>
> 1. If I use instance field 'name' which is accessed directly by other
> classes,
> and later I decide to implement nonstandard getter, I must refactor
> 'Person' class
> and in some places change 'name' to '_name' (assuming this is now the
> field's name).
> The problem is that I cannot automatically change 'name' to '_name'
> everywhere, because
> in some places I want public property value (eg. validated and
> formatted), and in other
> places raw property value.


In practice, it turns out to be a lot less work to deal with that
occasionally than to always deal with lugging around internal
attributes and external properties when they're really not needed. By
writing everything as properties up front you're just creating more
work for yourself, and it's generally considered bad practice in
Python to have default getters/setters (whether part of a property or
not).

> 2. Properties define (a part of) public interface of a class. When
> using fields for public
> access, you must tell this explicitly in documentation, or use name
> convention.


Property vs. attribute doesn't make any difference here: both of them
are public, and part of the external interface, unless they're named
with a leading underscore.

Making something a property doesn't make it any more or less a part of
the public interface.

> 3. Using properties as first-class objects gives possibilities to use
> declarative approaches
> for constructing them.


This doesn't make any sense. Properties and attributes are both
objects in python.

 
Reply With Quote
 
Artur Siekielski
Guest
Posts: n/a
 
      10-11-2007
On Oct 11, 4:21 pm, "(E-Mail Removed)" <(E-Mail Removed)> wrote:
> In practice, it turns out to be a lot less work to deal with that
> occasionally than to always deal with lugging around internal
> attributes and external properties when they're really not needed. By
> writing everything as properties up front you're just creating more
> work for yourself, and it's generally considered bad practice in
> Python to have default getters/setters (whether part of a property or
> not).


Ok, I appreciate your and Marc's argument. So I see that a pythonic
way is
using public attributes, and it works in real life. Automatic
"generation" of
getters/setters is a nice thing when using Java style of properties,
ie. no
public fields.

> > 2. Properties define (a part of) public interface of a class. When
> > using fields for public
> > access, you must tell this explicitly in documentation, or use name
> > convention.

>
> Property vs. attribute doesn't make any difference here: both of them
> are public, and part of the external interface, unless they're named
> with a leading underscore.


Nice thing about properites is that they are defined in more
declarative way -
in class body. Attributes are "defined" in a piece of code (which can
be long
and can contain loops etc.) by assigning a value to 'self'.

> > 3. Using properties as first-class objects gives possibilities to use
> > declarative approaches
> > for constructing them.

>
> This doesn't make any sense. Properties and attributes are both
> objects in python.


Attribute is an object which has value specific for the time it's get
from object.
It is separated from containing object - relation to it is lost.
Python property is an object that describes how to get/set a specific
attribute of
containing object - any time. It describes relationship between the
two.

By declarative method I mean something like a function that takes a
property object
and returns modified property object:

def not_none(prop):
def new_fset(self, obj):
if obj is not None:
prop.fset(self, obj)
else:
raise 'Cannot set None value'
return property(prop.fget, new_fset, prop.fdel)

And then:

class Person(object):
....
name = not_none( property(_get_name, _set_name) )

 
Reply With Quote
 
Marc 'BlackJack' Rintsch
Guest
Posts: n/a
 
      10-11-2007
On Thu, 11 Oct 2007 15:39:29 +0000, Artur Siekielski wrote:

> On Oct 11, 4:21 pm, "(E-Mail Removed)" <(E-Mail Removed)> wrote:
>> > 2. Properties define (a part of) public interface of a class. When
>> > using fields for public access, you must tell this explicitly in
>> > documentation, or use name convention.

>>
>> Property vs. attribute doesn't make any difference here: both of them
>> are public, and part of the external interface, unless they're named
>> with a leading underscore.

>
> Nice thing about properites is that they are defined in more declarative
> way - in class body. Attributes are "defined" in a piece of code (which
> can be long and can contain loops etc.) by assigning a value to 'self'.


The convention is to bind all attributes in `__init__()`, possibly to
`None` if the real value is not available at that time, and document at
least the public ones in the class' docstring. Tools like `pylint` check
for attributes that are introduced in other methods than `__init__()` and
give a warning.

Ciao,
Marc 'BlackJack' Rintsch
 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      10-11-2007
Artur Siekielski a écrit :
> Hi.
>
> I would like to have declarative properties in Python, ie. something
> like slots definitions in defclass in Common Lisp. It seems that even
> Java will have it, using a library ( https://bean-properties.dev.java.net/
> ).
>
> I know about 'property' function


Actually, it's a class.

> in Python, but it's normal usage
> isn't declarative, because I have to code imperatively getters and
> setters:


Indeed. What would be the use of a property (AKA computed attribute) if
you don't need to do something specific ?

> class Person(object):
> def __init__(self, name):
> self._name = name
> def _get_name(self):
> return self._name
> def _set_name(self, new_name):
> self._name = new_name
> name = property(_get_name, _set_name)


While it's often seen as demonstration code for a property, it's
actually totally useless. If all you want to do is to get and set an
attribute (I mean, without any computation anywhere), then just use an
attribute - you will always be able to turn it into a property if and
whene the need arises.

> I would like to have something like that:
>
> class Person(object):
> name = property('_name')
>
> I assume that this causes "generation" of instance field '_name' and
> default getters and setters.


So far, it's a waste of time. That's exactly what you'd get with a plain
attribute, with far less complexity and overhead.

> And if I would like to customize (g|
> s)etters, I would write them by hand,


Which bring us back to how properties actually work !-)

> or, better, use more declarative
> approach (like @NotNull annotations in Java version).


> I could probably code a solution to my problem with help of wonderful
> introspection functionalities. But I'm looking for a standard and/or
> proven way of doing this. Maybe some PEP is being prepared for this?


I guess you want to have a look at the descriptor protocol - it's what
makes properties work, and it allow you to write your own custom 'smart
attributes'. If you want automatic validation/conversion, you could
write custom descriptors working with the FormEncode package (I started
such a thing for Elixir, but had no time to finish it so far). It would
then looks like:

class Person(object):
name = StringField(empty=False)

// etc

HTH
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Interdependent DropDownLists (with declarative data binding) =?Utf-8?B?VGltbQ==?= ASP .Net 11 06-29-2006 06:49 AM
Declarative use of sqlDataSource in ASP.net 2.0 and Exception Hand =?Utf-8?B?SmVmZkRvdE5ldA==?= ASP .Net 1 02-02-2006 05:35 AM
Help Pls - declarative data binding =?Utf-8?B?QmlsbDQ0MDc3?= ASP .Net 4 01-27-2006 07:50 PM
declarative binding inside a gridview John ASP .Net 0 12-13-2005 06:36 PM
Declarative Security in ASP .net MS Newsgroups ASP .Net 1 10-19-2003 07:21 AM



Advertisments