type vs. module (part2)

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Oct 17 02:32:00 EDT 2011


On Sun, 16 Oct 2011 16:11:18 -0700, Shane wrote:

> In the following t,t1 are the result of built-in call type() -- the form
> that takes three arguments.

Are you sure about that? Because my explanation below will depend 
entirely on this alleged fact: that t and t1 themselves are classes, not 
instances.

To be sure (well, *nearly* sure), please print t and t1 and see whether 
you get something like:

print t
=> <class 'blah-blah-blah'>

or 

print t
=> <blah-blah-blah object at 0x9c5c64c>



> Therefore they are classes. Consider the following output:
> 
> print type(t)
>><class 'a.b.f.F'>
> print id(t)
>>1234567
> print t.__module__
>>a.b.t.d
> 
> print type(t1)
>><class 'a.b.f.F'>
> print id(t1)
>>1234568
> print t1.__module__
>>a.b.t.d
> 
> I now have two questions: How does Python allow two classes of the same
> type as evidenced by identical ``print type(<class>)' output and
> different id outputs?

When you use the class statement, you end up with one class with one 
name, but that's not a hard rule about classes. It's just a convention.


You can have multiple identical classes so long as you assign them to 
different names. For example:

>>> class Spam:  # bind a class "Spam" to the global name "Spam"
...     pass
...
>>> Ham = Spam  # bind the class object to another global name
>>>
>>> class Spam:  # and re-use the old name for a new class
...     x = 1
...
>>> print Ham, Spam
__main__.Spam __main__.Spam


What's going on here? The secret is that classes (and functions!) 
generally have *two* names. The first name is their internal name, the 
name they report when you print them. The second is the name of the 
variable (or variables!) they are bound to. Nobody says that they MUST 
match, although they often do.


When you use the class statement, Python's interpreter ensures that you 
start off with the two names matching, but as you can see from above, 
they don't necessarily stay matching. But the type() function doesn't 
enforce that:

>>> brie = type('cheese', (), {})
>>> cheddar = type('cheese', (), {})
>>> brie is cheddar
False
>>> print brie, cheddar
<class '__main__.cheese'> <class '__main__.cheese'>

Both brie and cheddar know their own name as "cheese", but the names you 
use to refer to them are different.



So, bringing this back to your examples... 

Both t and t1 are classes, both know their internal name as "F", but they 
are different classes, as seen by the fact that their IDs are different.


> Also, which module is t,t1 actually in? Is it "a.b.f"? Or is it
> "a.b.t.d".

Since they are two independent classes, it could easily be "both, one for 
each".



-- 
Steven



More information about the Python-list mailing list