per instance descriptors

S

Simon Bunker

Hi I have code similar to this:

class Input(object):

def __init__(self, val):
self.value = val

def __get__(self, obj, objtype):
return self.value

def __set__(self, obj, val):
# do some checking... only accept floats etc
self.value = val

class Node(object):

a = Input(1)
b = Input(2)

I realise that a and b are now class attributes - however I want to do this:

node1 = Node()
node2 = Node()

node1.a = 3
node.b = 4

And have them keep these values per instance. However now node1.a is 4
when it should be 3.

Basically I want to have the Input class as a gateway that does lots of
checking when the attibute is assigned or read.

I have had a look at __getattribute__(), but this gets very ugly as I
have to check if the attribute is an Input class or not.

Also I don't think property() is appropriate is it? All of the
attributes will essentially be doing the same thing - they should not
have individual set/get commands.

Is there any way of doing this nicely in Python?

thanks

Simon
 
G

George Sakkis

Simon said:
Hi I have code similar to this:

class Input(object):

def __init__(self, val):
self.value = val

def __get__(self, obj, objtype):
return self.value

def __set__(self, obj, val):
# do some checking... only accept floats etc
self.value = val

class Node(object):

a = Input(1)
b = Input(2)

I realise that a and b are now class attributes - however I want to do this:

node1 = Node()
node2 = Node()

node1.a = 3
node.b = 4

And have them keep these values per instance. However now node1.a is 4
when it should be 3.

Basically I want to have the Input class as a gateway that does lots of
checking when the attibute is assigned or read.

I have had a look at __getattribute__(), but this gets very ugly as I
have to check if the attribute is an Input class or not.

Also I don't think property() is appropriate is it? All of the
attributes will essentially be doing the same thing - they should not
have individual set/get commands.

Is there any way of doing this nicely in Python?

What about __setattr__ ? At least from your example, checking happens
only when you set an attribute. If not, post a more representative
sample of what you're trying to do.

George
 
G

Gabriel Genellina

What about __setattr__ ? At least from your example, checking happens
only when you set an attribute. If not, post a more representative
sample of what you're trying to do.

Or search the Python Cookbook - there are zillions of variants on how
to manage properties (using inner classes, using decorators, using
closures, using ...). Traits (code.enthought.com) may be useful too.


--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
 
C

Carl Banks

Simon said:
Hi I have code similar to this:

class Input(object):

def __init__(self, val):
self.value = val

def __get__(self, obj, objtype):
return self.value

def __set__(self, obj, val):
# do some checking... only accept floats etc
self.value = val

class Node(object):

a = Input(1)
b = Input(2)

I realise that a and b are now class attributes - however I want to do this:

node1 = Node()
node2 = Node()

node1.a = 3
node2.b = 4

And have them keep these values per instance. However now node1.a is 4
when it should be 3. [snip]
Is there any way of doing this nicely in Python?

The easiest way is to store the value in a hidden attribute of the
object. For instance:

class Input(object):
def __init__(self,default,name):
self.default = default
self.name = name # or, create a name automatically
def __get__(self,obj,objtype):
return getattr(obj,self.name,self.default)
def __set__(self,obj,value):
setattr(obj,self.name,value)

class Node(object):
a = Input(1,"_a")
b = Input(2,"_b")


Carl Banks
 
S

simon

George said:
What about __setattr__ ? At least from your example, checking happens
only when you set an attribute. If not, post a more representative
sample of what you're trying to do.

George

Yes, but I am setting it in the Node class aren't I? Wouldn't I need to
define __setattr__() in class Node rather than class Input? I don't
want to do this. Or am I getting confused here?

thanks

Simon
 
G

George Sakkis

Yes, but I am setting it in the Node class aren't I? Wouldn't I need to
define __setattr__() in class Node rather than class Input? I don't
want to do this. Or am I getting confused here?

Yes, __setattr__ would be defined in Node and Input would go. It seems
to me that the only reason you introduced Input was to implement this
controlled attribute access, and as you see it doesn't work as you want
it to. Why not define Node.__setattr__ ?

George
 
S

Simon Bunker

George said:
Yes, __setattr__ would be defined in Node and Input would go. It seems
to me that the only reason you introduced Input was to implement this
controlled attribute access, and as you see it doesn't work as you want
it to. Why not define Node.__setattr__ ?

George

The __setattr__ approach is what I am hoping to avoid.

Having the input class means that I just need to assign a class to an
attribute rather than having to filter each attribute name - really
annoying as there will be several classes similar to Node with different
attributes, but which should be handled in the same way.

Frankly descriptors seems exactly what I want - but having them as class
attributes makes them completely useless!

Simon
 
S

Simon Bunker

Carl said:
Simon said:
Hi I have code similar to this:

class Input(object):

def __init__(self, val):
self.value = val

def __get__(self, obj, objtype):
return self.value

def __set__(self, obj, val):
# do some checking... only accept floats etc
self.value = val

class Node(object):

a = Input(1)
b = Input(2)

I realise that a and b are now class attributes - however I want to do this:

node1 = Node()
node2 = Node()

node1.a = 3
node2.b = 4

And have them keep these values per instance. However now node1.a is 4
when it should be 3.
[snip]

Is there any way of doing this nicely in Python?


The easiest way is to store the value in a hidden attribute of the
object. For instance:

class Input(object):
def __init__(self,default,name):
self.default = default
self.name = name # or, create a name automatically
def __get__(self,obj,objtype):
return getattr(obj,self.name,self.default)
def __set__(self,obj,value):
setattr(obj,self.name,value)

class Node(object):
a = Input(1,"_a")
b = Input(2,"_b")


Carl Banks

This does seem the easiest way - but also a bit of a hack. Would it work
to assign to instance variables - each the class attribute sets the
instance attribute with the same name? Or would that not work?

Simon
 

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,773
Messages
2,569,594
Members
45,118
Latest member
LatishaWhy
Top