Getting a dictionary from an object
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Sun Jul 24 14:52:49 EDT 2005
Steven D'Aprano a écrit :
> On Sun, 24 Jul 2005 12:07:02 +0300, Thanos Tsouanas wrote:
>>
>>>Thanos Tsouanas wrote:
>>>
(snip)
>>I didn't know about it, but I knew about object.__dict__ which is, as I
>>see equivalent with vars(object). But it doesn't do the job for me,
>>since it fails to grab all obj.foo's, some of them being properties,
>>etc.
>
(snip)
> I don't think you are correct. As far as I can see, properties do have
> an entry in obj.__dict__ the same as other attributes, although there is
> certainly some strangeness going on with properties.
>
> Using the sample code from here:
> http://www.python.org/2.2.3/descrintro.html#property
>
> class C(object):
> def __init__(self):
> self.__x = 0
> def getx(self):
> return self.__x
> def setx(self, x):
> if x < 0: x = 0
> self.__x = x
> x = property(getx, setx)
>
> I see _C__x in C().__dict__, exactly as expected. (snip)
Yes, but you don't see 'x'. Poking into the object's __dict__ would
defeat the whole point of computed attributes - which by the way need
not directly map to a protected or private variable, nor even be
properties (think: descriptors).
> I can't see any way to inspect a Python object and get a list of
> properties,
I do :
def list_properties(obj):
proptype = type(property()) # not defined in types
klass = obj.__class__
names = dir(klass) # so we get inherited attribs as well
d = dict([(name, getattr(klass, name)) for name in names])
return [name for name, attrib in d.items() \
if type(attrib) is proptype]
Note that this won't find all descriptors (I've tried and it really
harder... there are a lot of things in a class.__dict__ that have a
__get__() method, most of'em not defined in the types module).
Anyway, you won't need it... (I mean, the OP don't need it to solve it's
problem)
> so you might have to keep your own list: add a class-attribute
> of your object which keeps a list of all the properties:
>
> class Obj:
> # various methods, attributes and properties
> ...
> # keep a list of special properties that don't show
> # up correctly in __dict__
> special = ['foo', 'bar']
>
> # now define a special method that makes a copy of
> # __dict__ and adds special properties to it
>
> def objdict(self):
> D = self.__dict__.copy()
> # assume shallow copy is enough
> for property_name in self.special:
> D[property_name] = self.__getattribute__(property_name)
> return D
>
> then call it when you need it:
>
> print "My object has fields %(foo)s and %(bar)s." % obj.objdict()
This means adding responsabilities to the class when the need is
obviously orthogonal to the class's responsabilities. Implementing a
generic decorator pattern in Python does'nt require more code, doesn't
requires the class nor the object to be modified at all, is probably
more robust, and is, well... more generic !-) (should I say 'more
pythonic' ?)
> It would be nice to see an easier way to introspect objects and get
> a list of properties.
You're dream is now reality. Now ain't *that* nice ?-)
Bruno
More information about the Python-list
mailing list