@x.setter property implementation

  • Thread starter Floris Bruynooghe
  • Start date
F

Floris Bruynooghe

Hello

I found out about the new methods on properties, .setter()
and .deleter(), in python 2.6. Obviously that's a very tempting
syntax and I don't want to wait for 2.6...

It would seem this can be implemented entirely in python code, and I
have seen hints in this directrion. So before I go and try to invent
this myself does anyone know if there is an "official" implementation
of this somewhere that we can steal until we move to 2.6?


Cheers
Floris
 
D

Daniel Fetchinson

I found out about the new methods on properties, .setter()
and .deleter(), in python 2.6. Obviously that's a very tempting
syntax and I don't want to wait for 2.6...

It would seem this can be implemented entirely in python code, and I
have seen hints in this directrion. So before I go and try to invent
this myself does anyone know if there is an "official" implementation
of this somewhere that we can steal until we move to 2.6?

The 2.6 source?
 
F

Floris Bruynooghe

The 2.6 source?

Have been grepping all over the place and failed to find it. I found
the test module for them, but that doesn't get me very far...
 
A

Andrii V. Mishkovskyi

2008/4/7 said:
Have been grepping all over the place and failed to find it. I found
the test module for them, but that doesn't get me very far...

I think you should take a look at 'descrobject.c' file in 'Objects' directory.
 
F

Floris Bruynooghe

2008/4/7, Floris Bruynooghe <[email protected]>:




I think you should take a look at 'descrobject.c' file in 'Objects' directory.


Thanks, I found it! So after some looking around here was my
implementation:

class myproperty(property):
def setter(self, func):
self.fset = func

But that doesn't work since fset is a read only attribute (and all of
this is implemented in C).

So I've settled with the (nearly) original proposal from Guido on
python-dev:

def propset(prop):
assert isinstance(prop, property)
@functools.wraps
def helper(func):
return property(prop.fget, func, prop.fdel, prop.__doc__)
return helper

The downside of this is that upgrade from 2.5 to 2.6 will require code
changes, I was trying to minimise those to just removing an import
statement.

Regards
Floris
 
A

Arnaud Delobelle

Thanks, I found it!  So after some looking around here was my
implementation:

class myproperty(property):
    def setter(self, func):
        self.fset = func

But that doesn't work since fset is a read only attribute (and all of
this is implemented in C).

So I've settled with the (nearly) original proposal from Guido on
python-dev:

def propset(prop):
    assert isinstance(prop, property)
    @functools.wraps
    def helper(func):
        return property(prop.fget, func, prop.fdel, prop.__doc__)
    return helper

The downside of this is that upgrade from 2.5 to 2.6 will require code
changes, I was trying to minimise those to just removing an import
statement.

Regards
Floris

Here's an implementation of prop.setter in pure python < 2.6, but
using sys._getframe, and the only test performed is the one below :)

import sys

def find_key(mapping, searchval):
for key, val in mapping.iteritems():
if val == searchval:
return key

_property = property

class property(property):
def setter(self, fset):
cls_ns = sys._getframe(1).f_locals
propname = find_key(cls_ns, self)
# if not propname: there's a problem!
cls_ns[propname] = property(self.fget, fset,
self.fdel, self.__doc__)
return fset
# getter and deleter can be defined the same way!

# -------- Example -------

class Foo(object):
@property
def bar(self):
return self._bar
@bar.setter
def setbar(self, x):
self._bar = '<%s>' % x

# -------- Interactive test -----
Having fun'ly yours,
 
F

Floris Bruynooghe

Thanks, I found it! So after some looking around here was my
implementation:
class myproperty(property):
def setter(self, func):
self.fset = func
But that doesn't work since fset is a read only attribute (and all of
this is implemented in C).
So I've settled with the (nearly) original proposal from Guido on
python-dev:
def propset(prop):
assert isinstance(prop, property)
@functools.wraps
def helper(func):
return property(prop.fget, func, prop.fdel, prop.__doc__)
return helper
The downside of this is that upgrade from 2.5 to 2.6 will require code
changes, I was trying to minimise those to just removing an import
statement.
Regards
Floris

Here's an implementation of prop.setter in pure python < 2.6, but
using sys._getframe, and the only test performed is the one below :)

import sys

def find_key(mapping, searchval):
for key, val in mapping.iteritems():
if val == searchval:
return key

_property = property

class property(property):
def setter(self, fset):
cls_ns = sys._getframe(1).f_locals
propname = find_key(cls_ns, self)
# if not propname: there's a problem!
cls_ns[propname] = property(self.fget, fset,
self.fdel, self.__doc__)
return fset
# getter and deleter can be defined the same way!

# -------- Example -------

class Foo(object):
@property
def bar(self):
return self._bar
@bar.setter
def setbar(self, x):
self._bar = '<%s>' % x

# -------- Interactive test -----
'<oeufs>'

Having fun'ly yours,

Neat!

Unfortunatly both this one and the one I posted before work when I try
them out on the commandline but both fail when I try to use them in a
module. And I just can't figure out why.

Floris
 
F

Floris Bruynooghe

On Apr 10, 3:37 pm, Floris Bruynooghe <[email protected]>
wrote:
Here's an implementation of prop.setter in pure python < 2.6, but
using sys._getframe, and the only test performed is the one below :)
import sys
def find_key(mapping, searchval):
for key, val in mapping.iteritems():
if val == searchval:
return key
_property = property
class property(property):
def setter(self, fset):
cls_ns = sys._getframe(1).f_locals
propname = find_key(cls_ns, self)
# if not propname: there's a problem!
cls_ns[propname] = property(self.fget, fset,
self.fdel, self.__doc__)
return fset
# getter and deleter can be defined the same way!
# -------- Example -------
class Foo(object):
@property
def bar(self):
return self._bar
@bar.setter
def setbar(self, x):
self._bar = '<%s>' % x
# -------- Interactive test -----


Having fun'ly yours,

Neat!

Unfortunatly both this one and the one I posted before work when I try
them out on the commandline but both fail when I try to use them in a
module. And I just can't figure out why.

This in more detail: Imaging mod.py:

import sys

_property = property

class property(property):
"""Python 2.6/3.0 style property"""
def setter(self, fset):
cls_ns = sys._getframe(1).f_locals
for k, v in cls_ns.iteritems():
if v == self:
propname = k
break
cls_ns[propname] = property(self.fget, fset,
self.fdel, self.__doc__)
return fset


class Foo(object):
@property
def x(self):
return self._x

@x.setter
def x(self, v):
self._x = v + 1


Now enter the interpreter:4

I don't feel like giving up on this now, so close...
 
A

Arnaud Delobelle

On Apr 11, 11:19 am, Floris Bruynooghe <[email protected]>
wrote:
[...]
Unfortunatly both this one and the one I posted before work when I try
them out on the commandline but both fail when I try to use them in a
module.  And I just can't figure out why.

This in more detail: Imaging mod.py:

import sys

_property = property

class property(property):
    """Python 2.6/3.0 style property"""
    def setter(self, fset):
        cls_ns = sys._getframe(1).f_locals
        for k, v in cls_ns.iteritems():
            if v == self:
                propname = k
                break
        cls_ns[propname] = property(self.fget, fset,
                                    self.fdel, self.__doc__)
        return fset

class Foo(object):
    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, v):
^^^^^
Don't call this 'x', it will override the property, change it to
'setx' and everything will work. The same probably goes for your own
'propset' decorator function.
 
F

Floris Bruynooghe

Oh, that was a good hint! See inline

On Apr 11, 11:19 am, Floris Bruynooghe <[email protected]>
wrote:
[...]
This in more detail: Imaging mod.py:
import sys
_property = property
class property(property):
"""Python 2.6/3.0 style property"""
def setter(self, fset):
cls_ns = sys._getframe(1).f_locals
for k, v in cls_ns.iteritems():
if v == self:
propname = k
break
cls_ns[propname] = property(self.fget, fset,
self.fdel, self.__doc__)
return fset

return cls_ns[propname]

And then it works as I tried originally!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top