user1050619
user1050619

Reputation: 20856

Python classes -- attributes not visible

I'm trying to create 2 objects,

  1. A by defining as a regular Python class
  2. B by dynamically creating properties.

Once both the classes are created, I'm trying to print their dictionary and noticed that for Class B which is dynamically created the attribute "X" is not listed.

class A(object):
    def __init__(self,x,y):
        self.x = 0
        self.y = 0


x = A(1,2)
print "Class A directory =",dir(x)

class B:pass
B().x = 5
y = B()
print "Class A directory =",dir(y)

Output

Class A directory = ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'x', 'y']
Class B directory = ['__doc__', '__module__']

Upvotes: 0

Views: 1428

Answers (1)

BrenBarn
BrenBarn

Reputation: 251355

B() creates an instance of B. When you do B().x = 5, you create an instance, set the x attribute, and then discard the instance (since you didn't assign the B() to anything). Then you create another instance with y = B(), but this instance isn't affected by what you did to the previous one.

You can do:

y = B()
y.x = 5

However, you have a couple terminological misunderstandings. In both of your examples you're calling dir on the instance, not the class. If you print dir(A) or dir(B), you'll see that the x attribute is not listed in either case, since it exists only on instances of the class, not on the class itself.

Also, it's not really correct to say that B is "created dynamically" while A is "defined as a regular Python class". They're both regular Python classes. It's just that class A is defined to create an attribute x in initialization, while class B isn't (and you then add an attribute to its instance later). Class B is still a normal Python class, it just has different defined behavior than A. (Note that you could add extra attributes to instances of A just like you did for B, by doing something like x = A(); x.newAttr = "blah".)

Also, you mention metaclasses in your title, but you're not using metaclasses at all here.

Upvotes: 8

Related Questions