[Baypiggies] A properties and obj.__dict__ question

Eric Walstad ewalstad at gmail.com
Fri Sep 9 07:20:04 CEST 2011


And now that I'm in front of a computer, an example:

>>> class Classtionary(dict):
...     def __init__(self, **kwargs):
...         self.__dict__ = self
...         self.update(kwargs)
>>> message = """
...     Name: %(name)s
...     Address: %(address)s
...     %(city)s, %(state)s  %(postal_code)s
...  """
>>>
>>> data = Classtionary(
...     name="Glen",
...     address="123 Your Street",
...     city="San Francisco",
...     state="CA",
...     postal_code="94131"
... )
>>> print(message % data)

    Name: Glen
    Address: 123 Your Street
    San Francisco, CA  94131


Best,

Eric.
On Thu, Sep 8, 2011 at 10:08 PM, Eric Walstad <ewalstad at gmail.com> wrote:
> Hey Glen
>
> I was working on something similar the other day and came up with a class
> that might work for you here.  The class is derived from dict and sets it's
> __dict__ to self
>
> http://pastebin.com/tk7sa7tz
>
> Hth
>
> Eric
>
> On Sep 8, 2011 8:51 PM, "Glen Jarvis" <glen at glenjarvis.com> wrote:
>> I have a question that is hard to ask without involving code. I reduced my
>> project down to a tiny test case (as follows).
>>
>> As you see, the following code will work and access the variables within
>> the
>> class successfully. However, it's a cheat, using the internal attributes
>> instead of the properties (as properties don't show in __dict__).
>>
>> The objective is to have a large string with different fields. The fields
>> happen to all be members of my class. So, I could hard code things like
>> this:
>>
>> message = """
>> Name: %s
>> Address: %s
>> %s, %s %s
>> """ % {obj.name, obj.address, obj.city, obj.state, obj.postal_code}
>>
>> But, as each of the items are properties of the class, I'd like to be more
>> dynamic, like this:
>>
>> message = """
>> Name: %(obj.name)s
>> Address: %(obj.address)s
>> %(obj.city)s, %(obj.state)s %(obj.postal_code)s
>> """ % obj
>>
>> I can do this with normal attributes, like the following:
>>
>> message = """
>> Name: %(name)s
>> Address: %(address)s
>> %(city)s, %(state)s %(postal_code)s
>> """ % obj.__dict__
>>
>> However, these attributes in my case are properties and don't show in the
>> __dict__.
>>
>> Here's a runnable piece of code to demonstrate:
>>
>>
>> =-=-=-=-=-=-=- Start of Working Code -=-=-=-=-=-=-=-=-=-
>> class Piggie(object):
>> def __init__(self):
>> """A demo for a BayPIGgies question"""
>> self._name = None
>> self._address = None
>>
>> @property
>> def name(self):
>> return self._name
>>
>> @name.setter
>> def name(self, value):
>> if isinstance(value, basestring):
>> value = value.strip()
>> self._name = value
>>
>> @property
>> def address(self):
>> return self._address
>>
>> @address.setter
>> def address(self, value):
>> if isinstance(value, basestring):
>> value = value.strip()
>> self._address = value
>>
>> def __unicode__(self):
>> if self.name is None:
>> return u"Nameless Person"
>> else:
>> return self.name
>> __str__ = __unicode__
>>
>>
>> f = Piggie()
>> f.name = 'Glen'
>>
>>
>> message = """
>> Obviously, this is silly for only two fields like this.
>>
>> But, it's a very reduced test case to demo a problem from a
>> much larger project.
>>
>> Name: %(_name)s
>> Address: %(_address)s
>> """ % f.__dict__
>>
>> print message
>> =-=-=-=-=-=-=- Start of Working Code -=-=-=-=-=-=-=-=-=-
>>
>>
>> This works, as the output below shows. However, only by accessing the
>> internal attributes of the class directly, not using the property
>> accessors.
>> How can I do something like this, but with property accessors. Something
>> like dir(f) or f.__property_dict__ that just has the properties.
>>
>> Run:
>>
>>
>> Obviously, this is silly for only two fields like this.
>>
>> But, it's a very reduced test case to demo a problem from a
>> much larger project.
>>
>> Name: Glen
>> Address: None
>>
>>
>>
>> Run with the properties used:
>>
>> Traceback (most recent call last):
>> File "x.py", line 48, in <module>
>> """ % f.__dict__
>> KeyError: 'name'
>>
>>
>> Thanks, for letting me share :)
>>
>>
>>
>> Glen
>> --
>> Things which matter most must never be at the mercy of things which matter
>> least.
>>
>> -- Goethe
>


More information about the Baypiggies mailing list