Re: Dynamically creating class properties

2007-10-04 Thread Michael Spencer
Karlo Lozovina wrote:

> 
> Any idea how to do that with metaclasses and arbitrary long list of 
> attributes? I just started working with them, and it's driving me nuts :).
> 
> Thanks for the help,
> best regards.
> 
Try implementing a property factory function before worrying about the 
metaclass.  Assuming you need a standard getter and setter, then the following 
(untested) example may be useful.  If you need custom get/set behavior then you 
would rewrite the factory to accept passed-in functions.

  >>> def make_data_property(cls, prop_name):
  ...
  ... # create default methods that get and set a 'private' instance
  ... # attribute
  ... def _set(self, value):
  ... setattr(self, "_%s" % prop_name, value)
  ... def _get(self):
  ... # None is default.  Alternatively handle AttributeError
  ... return getattr(self, "_%s" % prop_name, None)
  ...
  ... setattr(cls, prop_name, property(_get, _set))
  ...
  ... # optionally, fix the internal names of the _get and _set for better
  ... # introspection
  ... _set.func_name = setname = "set%s" % prop_name
  ... _get.func_name = getname = "get%s" % prop_name
  ...
  ... # optionally, make _get and _set members of the class, if you want to
  ... # call them directly (but then, why have the property?)
  ... setattr(cls, setname, _set)
  ... setattr(cls, getname, _get)
  ...
  >>> class A(object):
  ... pass
  ...
  >>> a=A()
  >>> a.item1
  Traceback (most recent call last):
File "", line 1, in 
  AttributeError: 'A' object has no attribute 'item1'
  >>> make_data_property(A,"item1")
  >>> a.item1
  >>> a.item1 = 42
  >>> a.item1
  42
  >>> make_data_property(A,"item2")
  >>> a.item2
  >>> a.item2 = 43
  >>>
  >>> a.item2
  43
  >>>

If you can get this piece working, then multiple attributes should be easy. 
Then, if you like, you can call your property factory from the metaclass 
__init__ method.

HTH
Michael

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Dynamically creating class properties

2007-10-04 Thread Paul Hankin
On Oct 4, 11:55 pm, Paul Hankin <[EMAIL PROTECTED]> wrote:
> On Oct 4, 9:59 pm, Karlo Lozovina <[EMAIL PROTECTED]> wrote:
>
>
>
> > Hi all,
>
> > this is my problem: lets say I have a arbitrary long list of attributes
> > that I want to attach to some class, for example:
>
> >  l = ['item1', 'item2', 'item3']
>
> > Using metaclasses I managed to create a class with those three
> > attributes just fine. But now I need those attributes to be properties,
> > so for example if 'A' is my constructed class, and 'a' an instance of
> > that class:
>
> > a = A()
>
> > Now if I write:
>
> > a.item1 = 'something'
> > print a.item1
>
> > I want it to be actually:
>
> > a.setitem1('something')
> > print a.getitem1
>
> > Any idea how to do that with metaclasses and arbitrary long list of
> > attributes? I just started working with them, and it's driving me nuts :).
>
> No metaclasses, but how about this?
>
> def make_class(name, attributes):
> # Build class dictionary.
> d = dict(_attributes=list(attributes))
> # Add in getters and setters from global namespace.
> for attr in attributes:
> d[attr] = property(globals()['get' + attr],
> globals()['set' + attr])
> # Construct our class.
> return type(name, (object,), d)

Sorry, I'm adding '_attributes' unnecessarily to the class dictionary.
The dictionary should be just initialised with d = {} before the
properties are added.

--
Paul Hankin

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Dynamically creating class properties

2007-10-04 Thread Paul Hankin
On Oct 4, 9:59 pm, Karlo Lozovina <[EMAIL PROTECTED]> wrote:
> Hi all,
>
> this is my problem: lets say I have a arbitrary long list of attributes
> that I want to attach to some class, for example:
>
>  l = ['item1', 'item2', 'item3']
>
> Using metaclasses I managed to create a class with those three
> attributes just fine. But now I need those attributes to be properties,
> so for example if 'A' is my constructed class, and 'a' an instance of
> that class:
>
> a = A()
>
> Now if I write:
>
> a.item1 = 'something'
> print a.item1
>
> I want it to be actually:
>
> a.setitem1('something')
> print a.getitem1
>
> Any idea how to do that with metaclasses and arbitrary long list of
> attributes? I just started working with them, and it's driving me nuts :).

No metaclasses, but how about this?

def make_class(name, attributes):
# Build class dictionary.
d = dict(_attributes=list(attributes))
# Add in getters and setters from global namespace.
for attr in attributes:
d[attr] = property(globals()['get' + attr],
globals()['set' + attr])
# Construct our class.
return type(name, (object,), d)


# Test code:

def getitem1(self):
return self._fred + 1

def setitem1(self, value):
self._fred = value

A = make_class('A', ['item1'])
a = A()

a.item1 = 19
print a.item1

>> 20


You didn't say where the getters and setters (here 'getitem1',
'setitem1', etc.) come from. I've assumed from the global namespace
but you probably want to change that.

--
Paul Hankin

-- 
http://mail.python.org/mailman/listinfo/python-list


Dynamically creating class properties

2007-10-04 Thread Karlo Lozovina
Hi all,

this is my problem: lets say I have a arbitrary long list of attributes 
that I want to attach to some class, for example:

 l = ['item1', 'item2', 'item3']

Using metaclasses I managed to create a class with those three 
attributes just fine. But now I need those attributes to be properties, 
so for example if 'A' is my constructed class, and 'a' an instance of 
that class:

a = A()

Now if I write:

a.item1 = 'something'
print a.item1

I want it to be actually:

a.setitem1('something')
print a.getitem1

Any idea how to do that with metaclasses and arbitrary long list of 
attributes? I just started working with them, and it's driving me nuts :).

Thanks for the help,
best regards.

-- 
Karlo Lozovina -- Mosor
-- 
http://mail.python.org/mailman/listinfo/python-list