[Baypiggies] A properties and obj.__dict__ question

Glen Jarvis glen at glenjarvis.com
Fri Sep 9 05:51:05 CEST 2011


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/baypiggies/attachments/20110908/d1c61869/attachment.html>


More information about the Baypiggies mailing list