class static variables and __dict__

Z

Zack

If I have a class static variable it doesn't show up in the __dict__ of
an instance of that class.

class C:
n = 4

x = C()
print C.__dict__
{'__module__': '__main__', '__doc__': None, 'n': 4}
print x.__dict__
{}

This behavior makes sense to me as n is not encapsulated in x's
namespace but what method can you use on x to find all available
attributes for that class?
 
D

Diez B. Roggisch

Zack said:
If I have a class static variable it doesn't show up in the __dict__ of
an instance of that class.

class C:
n = 4

x = C()
print C.__dict__
{'__module__': '__main__', '__doc__': None, 'n': 4}
print x.__dict__
{}

This behavior makes sense to me as n is not encapsulated in x's
namespace but what method can you use on x to find all available
attributes for that class?

x.__class__.__dict__

Diez
 
Z

Zack

Diez said:
x.__class__.__dict__

Diez

This would leave out any attributes of base classes. Not that I asked
for that functionality in my original post but is there a way to get all
attributes qualified by x. ? I see that I could walk the dict of x,
x.__class__ and x.__class__.__bases__ until I exhaust the tree. But is
there a built in method for doing this?
 
D

Dustan

what method can you use on x to find all available
attributes for that class?
bar = "hello, world!"
def __init__(self, baz):
self.baz = baz
['__class__', '__delattr__', '__dict__', '__doc__',
'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__',
'__weakref__', 'bar', 'baz']
 
Z

Zack

Zack said:
This would leave out any attributes of base classes. Not that I asked
for that functionality in my original post but is there a way to get all
attributes qualified by x. ? I see that I could walk the dict of x,
x.__class__ and x.__class__.__bases__ until I exhaust the tree. But is
there a built in method for doing this?

I believe this accomplishes what I'm looking for. I'm not positive it is
correct or if there are cases I've missed. It would be nice if there is
a simple python builtin for finding the fully qualified dict.

def fullDict(obj):
'''
Returns a dict with all attributes qualified by obj.

obj is an instance of a class

'''
d = obj.__dict__
# update existing items into new items to preserve inheritance
tmpD = obj.__class__.__dict__
tmpD.update(d)
d = tmpD
supers = list(obj.__class__.__bases__)
for c in supers:
tmpD = c.__dict__
tmpD.update(d)
d = tmpD
supers.extend(c.__bases__)
return d
 
Z

Zack

Dustan said:
what method can you use on x to find all available
attributes for that class?
bar = "hello, world!"
def __init__(self, baz):
self.baz = baz
x = Foo(42)
x.__dict__.keys() # Does not include bar
['baz']
dir(x) # Includes bar plus some methods
['__class__', '__delattr__', '__dict__', '__doc__',
'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__',
'__weakref__', 'bar', 'baz']

I knew there was something simple I was forgetting.
Thanks
 
D

Dustan

I believe this accomplishes what I'm looking for. I'm not positive it is
correct or if there are cases I've missed. It would be nice if there is
a simple python builtin for finding the fully qualified dict.

def fullDict(obj):
'''
Returns a dict with all attributes qualified by obj.

obj is an instance of a class

'''
d = obj.__dict__
# update existing items into new items to preserve inheritance
tmpD = obj.__class__.__dict__
tmpD.update(d)
d = tmpD
supers = list(obj.__class__.__bases__)
for c in supers:
tmpD = c.__dict__
tmpD.update(d)
d = tmpD
supers.extend(c.__bases__)
return d

I know you're probably dumping this for dir(), but I should still warn
you: This function modifies the class dictionary, which might not have
been what you intended.
 
Z

Zack

Dustan said:
I know you're probably dumping this for dir(), but I should still warn
you: This function modifies the class dictionary, which might not have
been what you intended.

I'm not actually do anything with this, or dir, just messing around
learning python (I would use dir instead of this if I had a need
though). I had completely missed that I wasn't copying the dicts. Thanks
for that catch.
 
7

7stud

Dustan said:
what method can you use on x to find all available
attributes for that class?
class Foo(object):
   bar = "hello, world!"
   def __init__(self, baz):
           self.baz = baz
x = Foo(42)
x.__dict__.keys() # Does not include bar ['baz']
dir(x) # Includes bar plus some methods
['__class__', '__delattr__', '__dict__', '__doc__',
'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__',
'__weakref__', 'bar', 'baz']

I knew there was something simple I was forgetting.
Thanks

dir() doesn't do it either:

-----
dir( [object])
Without arguments, return the list of names in the current local
symbol table. With an argument, attempts to return a list of valid
attributes for that object. This information is gleaned from the
object's __dict__ attribute, if defined, and from the class or type
object. ***The list is not necessarily complete.*** If the object is a
module object, the list contains the names of the module's attributes.
If the object is a type or class object, the list contains the names
of its attributes, and recursively of the attributes of its bases.
Otherwise, the list contains the object's attributes' names, the names
of its class's attributes, and recursively of the attributes of its
class's base classes. The resulting list is sorted alphabetically. For
example:

Note: Because dir() is supplied primarily as a convenience for use at
an interactive prompt, it tries to supply an interesting set of names
more than it tries to supply a rigorously or consistently defined set
of names, and its detailed behavior may change across releases.
 
A

Arnaud Delobelle

I believe this accomplishes what I'm looking for. I'm not positive it is
correct or if there are cases I've missed. It would be nice if there is
a simple python builtin for finding the fully qualified dict.

def fullDict(obj):
    '''
    Returns a dict with all attributes qualified by obj.

    obj is an instance of  a class

    '''
    d = obj.__dict__
    # update existing items into new items to preserve inheritance
    tmpD = obj.__class__.__dict__
    tmpD.update(d)
    d = tmpD
    supers = list(obj.__class__.__bases__)
    for c in supers:
       tmpD = c.__dict__
       tmpD.update(d)
       d = tmpD
       supers.extend(c.__bases__)
    return d

Child class attributes override base class ones, so your function will
get the wrong dict I think in cases like:

class A(object):
x = 1

class B(A):
x = 2

Why not do something like this:

def fulldict(obj):
d = {}
for t in reversed(type(obj).__mro__):
d.update(t.__dict__)
d.update(obj.__dict__)
return d
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top