473,394 Members | 1,965 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

property and virtuality


My problem is about properties and the virtuality of the methods. I
would like to create a property whose get and set methods
are virtual. I had the same problems in Delphi before and the solution
was the same. I created a private _get method and a public
get method. The former one will call the latter. The same stands for
_set and set. Here is an example below:

class C1(object):
def namechanged(self):
"""Called after the name of the component has been changed."""
pass
def getname(self):
"""Returns the name of the component.

You can override this method to provide generated component
names."""
return self._name
def setname(self,name):
"""Set the name of the component.

You can override this method to programatically control
component name changes.
"""
self._name = name
self.namechanged()
def _getname(self):
"""Internal method, do not use"""
return self.getname()
def _setname(self,name):
"""Internal method, do not use"""
self.setname(name)
name = property(_getname,_setname,"Name")

class C2(C1):
def getname(self):
return "lala"

class C3(C1):
def _getname(self):
return "lala"
name = property(_getname,None,"Name")
c1 = C1()
c2 = C2()
c3 = C3()

c1.name = 'Test1'
c2.name = 'Test2'
c3.name = 'Test3'
print c1.name # This will print 'Test1'
print c2.name # This will print 'lala'
print c3.name # This will print 'lala'
print C3.name is C1.name # False

I cannot override C2._getname instead, because c2.name would print
'Test2" instead of lala. Clearly, the property stores a reference to the
get and set methods and it is not possible to have it use the new
methods. Creating a new property is the worst - need to duplicate code
and also C3.name is C1.name returns False. :-) It is not a big problem
because I found the solution just I wonder if there is a better way to
"virtualize" property get/set functions.


--
__________________________________________________ _______________
Laszlo Nagy web: http://designasign.biz
IT Consultant mail: ga*****@geochemsource.com

Python forever!
Jul 18 '05 #1
11 1596
> I cannot override C2._getname instead, because c2.name would print
'Test2" instead of lala. Clearly, the property stores a reference to the
get and set methods and it is not possible to have it use the new
methods. Creating a new property is the worst - need to duplicate code
and also C3.name is C1.name returns False. :-) It is not a big problem
because I found the solution just I wonder if there is a better way to
"virtualize" property get/set functions.


I'm not aware of possibility that works as you first expected. You yourself
explained why.

But _maybe_ you can use lambda here - that creates the layer of indirection
one needs.

foo = property(lambda self: self.get_foo(), lamda self,v: self.set_foo(v))

On second thoughts, a metaclass _might_ help here - but it would be rather
elaborate: look in the baseclasses for properties that have getters and
setters of the same name as some methods in the current class, and replace
them, or create a new property with them (I'm not sure if descriptors
allow changing their get/set/del methods). I'm not 100% sure if and how
good that works (a quick hack would be easy, but to ship around the cliffs
of multiple inheritance requires more careful navigation I fear...)

--
Regards,

Diez B. Roggisch
Jul 18 '05 #2
I'm not aware of possibility that works as you first expected. You yourself
explained why.

But _maybe_ you can use lambda here - that creates the layer of indirection
one needs.

foo = property(lambda self: self.get_foo(), lamda self,v: self.set_foo(v))

Great. I'll think about this and decide which is better - lamba or
private functions. Lambda seems much
shorter but it is not as clear why it is there. :-)
On second thoughts, a metaclass _might_ help here - but it would be rather
elaborate: look in the baseclasses for properties that have getters and
setters of the same name as some methods in the current class, and replace
them, or create a new property with them (I'm not sure if descriptors
allow changing their get/set/del methods). I'm not 100% sure if and how
good that works (a quick hack would be easy, but to ship around the cliffs
of multiple inheritance requires more careful navigation I fear...)

Yes, I feel the same. Using a metaclass could be a small help but rather
elaborate and probably much slower.
Thank you for your help.
--
__________________________________________________ _______________
Laszlo Nagy web: http://designasign.biz
IT Consultant mail: ga*****@geochemsource.com

Python forever!
Jul 18 '05 #3
> Great. I'll think about this and decide which is better - lamba or
private functions. Lambda seems much
shorter but it is not as clear why it is there. :-)
I did put comments above each property line - so one might argue that's
about the same effort as writing the method explicit. Alternatively, you
could introduce a naming scheme in the getters/setters that are supposed to
be overloaded so that it becomes clear - at least for someone knowing the
project. But that's true for the whole thingy :) Yes, I feel the same. Using a metaclass could be a small help but rather
elaborate and probably much slower.


Certainly not much slower - that happens once, at class creation time - and
the results would even be faster, as you can skip the layer of indirection.

--
Regards,

Diez B. Roggisch
Jul 18 '05 #4
I think you may find Alex Martelli's PyCon slides somewhere
on the net. The black magic slides discuss this issue. But I
think the fix he suggests is not dissimilar from what you
are already doing. I don't remember exactly now, but
it is always worth a look.

Michele Simionato

Jul 18 '05 #5
Laszlo Zsolt Nagy wrote:

My problem is about properties and the virtuality of the methods. I
would like to create a property whose get and set methods
are virtual.


Perhaps you want to roll your own VirtualProperty descriptor? Here's
one based off the property implementation in Raymond Hettinger's How-To
Guide for Descriptors[1]:

py> class VirtualProperty(object):
.... def __init__(self, getname=None, setname=None, delname=None,
.... doc=None):
.... self.getname = getname
.... self.setname = setname
.... self.delname = delname
.... self.__doc__ = doc
.... def __get__(self, obj, type=None):
.... if obj is None:
.... return self
.... if self.getname is None:
.... raise AttributeError('unreadable attribute')
.... try:
.... fget = getattr(obj, self.getname)
.... except AttributeError:
.... raise TypeError('%s object does not have a %s method' %
.... (type(obj).__name__, self.getname))
.... return fget()
.... def __set__(self, obj, value):
.... if self.setname is None:
.... raise AttributeError("can't set attribute")
.... try:
.... fset = getattr(obj, self.setname)
.... except AttributeError:
.... raise TypeError('%s object does not have a %s method' %
.... (type(obj).__name__, self.setname))
.... fset(value)
.... def __delete__(self, obj):
.... if self.delname is None:
.... raise AttributeError("can't delete attribute")
.... try:
.... fdel = getattr(obj, self.delname)
.... except AttributeError:
.... raise TypeError('%s object does not have a %s method' %
.... (type(obj).__name__, self.delname))
.... fdel()
....
py> class C(object):
.... def getx(self):
.... return 'C'
.... x = VirtualProperty('getx', 'setx', 'delx')
....
py> class D(C):
.... def getx(self):
.... try:
.... return self._x
.... except AttributeError:
.... return 'D'
.... def setx(self, x):
.... self._x = x
....
py> c = C()
py> c.x
'C'
py> c.x = 1
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "<interactive input>", line 24, in __set__
TypeError: C object does not have a setx method
py> del c.x
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "<interactive input>", line 33, in __delete__
TypeError: C object does not have a delx method
py> d = D()
py> d.x
'D'
py> d.x = 1
py> d.x
1
py> del d.x
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "<interactive input>", line 33, in __delete__
TypeError: D object does not have a delx method

STeVe

[1] http://users.rcn.com/python/download/Descriptor.htm
Jul 18 '05 #6
Steven Bethard wrote:
Laszlo Zsolt Nagy wrote:
My problem is about properties and the virtuality of the methods. I
would like to create a property whose get and set methods
are virtual.


Perhaps you want to roll your own VirtualProperty descriptor? Here's
one based off the property implementation in Raymond Hettinger's How-To
Guide for Descriptors[1]:


This comes up often enough I figured it would be worth posting this as a
recipe:

http://aspn.activestate.com/ASPN/Coo.../Recipe/408713

STeVe
Jul 18 '05 #7
Hello,

I asked this question some time ago, but as I got no answer, so I just
try it a second
time.

I am working on a C extension module that implements a bunch of
classes. Everything
works fine so far, but I cannot find any way to implement class
attributes or inner
classes. Consider you have the following lines of Python :

class Foo :
class Bar :
pass

spam = "foobar"

How can this class be translated to a C extension? Is there anything
comparable to
PyMethodDef that can be used for other attributes than functions?

Thanks for your help,

- harold -

--
Always remember that you are unique;
just like everyone else.
--

Jul 18 '05 #8

"harold fellermann" <ha***************@upf.edu> wrote in message
news:d3******************************@upf.edu...
I asked this question some time ago, but as I got no answer, so I just
try it a second time.


This did get out, but I can't answer except to suggest looking at code for
other C extension modules. Nested (inner) classes are fairly rare, but I
presume that once you know how to add attributes in general, you add class
as an attribute in the same way you would add an int, etc, as an attribute.
(And if I am wrong, you should certainly get another response '-).

Terry J. Reedy

Jul 18 '05 #9
Laszlo Zsolt Nagy <ga*****@geochemsource.com> wrote in message news:<ma**************************************@pyt hon.org>...
My problem is about properties and the virtuality of the methods. I
would like to create a property whose get and set methods
are virtual. I had the same problems in Delphi before and the solution
was the same. I created a private _get method and a public
get method. The former one will call the latter.
[...]
I cannot override C2._getname instead, because c2.name would print
'Test2" instead of lala. Clearly, the property stores a reference to the
get and set methods and it is not possible to have it use the new
methods. Creating a new property is the worst - need to duplicate code
and also C3.name is C1.name returns False. :-) It is not a big problem
because I found the solution just I wonder if there is a better way to
"virtualize" property get/set functions.


Alex Martelli has demonstrated the same technique to "fix" this
disturbing property behavior during one of its talk at Pycon 2005:

http://www.python.org/pycon/2005/papers/36/ (slides p.7&8)

.... from this I infer that you found the best fix available ;)

Regards,

Sébastien
Jul 18 '05 #10
Diez B. Roggisch:
On second thoughts, a metaclass _might_ help here - but it would be rather elaborate: look in the baseclasses for properties that have getters and setters of the same name as some methods in the current class, and replace them, or create a new property with them (I'm not sure if descriptors allow changing their get/set/del methods). I'm not 100% sure if and how good that works (a quick hack would be easy, but to ship around the cliffs of multiple inheritance requires more careful navigation I fear...)


Maybe you are worrying to much. Here is a quick metaclass solution
which
magically generates properties from methods which name starts with
"get"
or "set":

class MagicProperties(type):
def __init__(cls, name, bases, dic):
prop_names = set(name[3:] for name in dic
if name.startswith("get")
or name.startswith("set"))
for name in prop_names:
getter = getattr(cls, "get" + name, None)
setter = getattr(cls, "set" + name, None)
setattr(cls, name, property(getter, setter))

class Base(object):
__metaclass__ = MagicProperties
def getx(self):
return self._x
def setx(self, value):
self._x = value

class Child(Base):
def getx(self):
print "getting x"
return super(Child, self).getx()
def setx(self, value):
print "setting x"
super(Child, self).setx(value)

c = Child()
c.x = 1
print c.x

This should work well for multiple inheritance too (modulo metaclass
conflicts).

I must say, however, that I never use this idiom (i.e. polluting my
classes
with tons of getters and setters and making properties from them).
I typically use a property factory function, or a custom descriptor.
Michele Simionato

Jul 18 '05 #11
Laszlo Zsolt Nagy wrote:

My problem is about properties and the virtuality of the methods. I
would like to create a property whose get and set methods
are virtual.


You might find the following function useful, which I
developed for use in PyGUI.

def overridable_property(name, doc = None):
"""Creates a property which calls methods get_xxx and set_xxx of
the underlying object to get and set the property value, so that
the property's behaviour may be easily overridden by subclasses."""

getter_name = intern('get_' + name)
setter_name = intern('set_' + name)
return property(
lambda self: getattr(self, getter_name)(),
lambda self, value: getattr(self, setter_name)(value),
None,
doc)

Usage example:

class MyClass(object):
...
spam = overridable_property('spam', "Favourite processed meat product")
...

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg
Jul 18 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Johnny M | last post by:
using Access 2003 Pardon the subject line, but I don't have a better word for this strange behavior (or behavior I don't understand!!!) I have a class module named DepreciationFactor. One of...
7
by: MP | last post by:
Hello, I am trying to write a class that will expose some properties. One of the property is extracted from a SQL database and can be NULL or some integer value. Is there a elegant way of...
3
by: MattC | last post by:
Hi, I found this code somewhere on the net and need to make some alterations. public class GenericSorter : IComparer { String sortProperty; bool sortOrder; public GenericSorter(String...
2
by: Edward Diener | last post by:
How does one specify in a component that a property is a pointer to another component ? How is this different from a property that is actually an embedded component ? Finally how is one notified in...
0
by: Brian Young | last post by:
Hi all. I'm using the Property Grid control in a control to manage a windows service we have developed here. The windows service runs a set of other jobs that need to be managed. The control...
3
by: Marty McFly | last post by:
Hello, I have a control class that inherits from System.Web.UI.WebControls.Button. When I drag this control from the "My User Controls" tab in the toolbox onto the form, I want it to reflect the...
0
by: Jordan Bowness | last post by:
I make a similar post in another newsgroup, but this example is simplified somewhat. I have a component (cmpMyComponent) with 2 properties. The 1st property is a string value (Description) and...
15
by: Lauren Wilson | last post by:
Owning your ideas: An essential tool for freedom By Daniel Son Thinking about going into business? Have an idea that you think will change the world? What if you were told that there was no way...
1
by: cday119 | last post by:
I have a Class with about 10 properties. All properties return right except for one. It is real annoying and I can't see why its not working. Maybe someone else can see something. It is the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.