[Tutor] new object attribute from string?
Danny Yoo
dyoo@hkn.eecs.berkeley.edu
Mon Apr 14 16:20:02 2003
On Mon, 14 Apr 2003 alan.gauld@bt.com wrote:
> > It is possible to dynamically add new attributes to our objects. Each
> > object in Python has an internal '__dict__' dictionary that
> > keeps track of all of its attributes:
> >
> > ###
> > >>> class TestAttribute:
> > ... def __init__(self, name):
> > ... self.name = name
> > ... def printInternals(self):
> > ... print "my dictionary looks like this:", self.__dict__
> >
> > And we're already very familiar with dictionaries: we can
> > easily add new attributes by assigning another key to
> > that __dict__ionary.
>
> But since we can achieve the same by simply assigning to a new attribute
> there is no need for such complexity
>
> >>> t1.question = 'new object attribute from string?'
>
> Achieves the same result
>
> > >>> t1.question
> > 'new object attribute from string?'
[warning; slightly advanced code ahead]
Hi Alan,
Yes, the direct way works too. *grin*
In certain really dynamic code, the attribute name itself may not known
until "runtime", when the program is actively running.
For example, here's a toy class that demonstrates the kind of dynamism we
can do in Python:
###
from __future__ import nested_scopes
class PleaseWrapper(object):
"""Wraps around an object and puts a please()ing wrapper around every
attribute of our class."""
def __init__(self, wrapped_object):
self.__wrapped_object = wrapped_object
for key, value in self.__wrapped_object.__dict__.items():
self.__dict__[key] = self.__makePleaseFunction(key, value)
def __makePleaseFunction(self, key, value):
class F(str):
def __init__(self2, message):
str.__init__(self2, message)
self2.__key = key
self2.__value = value
def please(self2):
return self2.__value
return F("say please()!")
###
The code may look a bit mysterious: what does it do? Well, let's say that
we had some class instance, like:
###
>>> class Person(object):
... def __init__(self, name):
... self.name = name
...
>>> p = Person("Danny")
>>> p.name
'Danny'
###
and let's say that we wanted it to be a little, well, annoying. *grin* We
can make another instance that looks like 'p', but forces us to ask it
'please()' to get the value of anything:
###
>>> p2 = PleaseWrapper(p)
>>> p2.name
'say please()!'
>>> p2.name.please()
'Danny'
###
This sort of dynamicism is possible when we can manipulate an object's
attributes through the dictionary interface.
Hope this helps!