Reputation: 552
I notice python won't let you add an instance of a class to itself as a static member at class definition.
>>> class Foo:
... A = Foo()
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in Foo
NameError: name 'Foo' is not defined
However either of the following work:
>>> class Foo:
... pass
...
>>> class Foo:
... A = Foo()
...
>>> Foo.A
<__main__.Foo instance at 0x100854440>
or
>>> class Foo:
... pass
...
>>> Foo.A = Foo()
>>>
>>> Foo.A
<__main__.Foo instance at 0x105843440>
I can't find any enlightening code examples or explanations. Why does python treat the first case differently? Where is A going in each of the two subsequent cases?
Upvotes: 3
Views: 896
Reputation: 2517
At class definition time, the class itself doesn't exist yet, the contents of the indented block are executed and any names are resolved and functions are called. At that point, the name of the class, the base classes and a dictionary containing the names and values to store in the class are passed off to the metaclass which creates the actual class and binds it to the name specified. You can create a 'static' instance of a class at class initialization time via the use of a metaclass
. This executes the code inside the class definition, passes the name, bases and dict to a metaclass function, which creates the class and creates an instance of the class inside it then binds it to the name. Consider:
def staticInstanceMetaclass(name, bases, dict_):
ret=type(name, bases, dict_)
for i in dict_:
if dict_[i]=='STATICINSTANCE':
setattr(ret,i,ret())
return ret
class ClassWithStaticInstance(object):
__metaclass__=staticInstanceMetaclass
myStaticInstance='STATICINSTANCE'
myFirstVar=5
print ClassWithStaticInstance.myStaticInstance
Note that in the above example, dict_
contains
{'myStaticInstance': 'STATICINSTANCE', '__module__': '__main__', '__metaclass__': <function staticInstanceMetaclass at 0x1213668>, 'myFirstVar': 5}
That's about as close as you get to pre-creating static instances in python. For more info on metaclasses, and how the affect class creation, see this question.
Upvotes: 0
Reputation: 4585
(EDIT : look at this question for examples of self-referencing classes in Python.)
I think this will spell it out :
>>> class Test:
... a = 3
...
>>> class Test:
... m = Test()
...
>>>
>>> t = Test()
>>> t.m
<__main__.Test object at 0x01E73690>
>>> t.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Test' object has no attribute 'a'
>>> t.m.a
3
Amazingly, that gives you two different classes with the same name. But I guess the first class is "lost" and only accessible through the second one.
Upvotes: 3
Reputation: 91119
Creating a class works by first evaluating its body and then, at the end, creating a class object.
So
class Foo:
A = Foo() # here class Foo doesn't exist yet
# but here it exists.
(Here is how creating a class object works.)
Your 2nd example creates a class and then creates another class with the same name, not related to the first one in any way. Thus,
>>> isinstance(Foo.A, Foo)
False
Your 3rd example uses the class after its creation to extend it.
So,
>>> isinstance(Foo.A, Foo)
True
Why does python treat the first case differently?
Because the identifier doesn't exist yet.
Where is A going in each of the two subsequent cases?
What does that mean, where is it going?
Upvotes: 1
Reputation: 60014
Your first example doesn't work because you haven't created the class Foo
yet. You're in the process of doing so (hence the NameError
)
Your second example works because you have a class called Foo()
. You override it, but you still keep a copy of it. Take a look at this:
>>> class Foo:
... def __init__(self):
... print 'hi'
...
>>> class Foo:
... A = Foo()
...
hi
>>> Foo.A
<__main__.Foo instance at 0x101019950>
>>> Foo.A.__init__
<bound method Foo.__init__ of <__main__.Foo instance at 0x101019950>>
A
is an attribute that has the value of a class you overrode.
As for your third example, you're simply making an attribute of a class that is an instance of the class.
Upvotes: 6