Vedran Čačić added the comment:

Yes, they are obviously not equivalent if you execute

    object = int

before that. :-D

And (like I said) "received wisdom" is also that "except:" is equivalent to 
"except BaseException:", but of course it isn't equivalent if you execute

    BaseException = NameError

before.

Rebinding the names for fundamental objects in Python doesn't change the 
semantics of these objects. Python interpreter is an external thing: it doesn't 
exist "in-universe". It doesn't refer to these objects by names in some 
currently-executing-Python-instance namespace, it refers to them externally. 
And, mostly, so do we when explaining how Python works.

Let me give you an analogy: In the old days, you could rebind True and False, 
for example by saying

    True, False = False, True

But of course, you would trivially understand that after such rebinding,

    if 6 > 4:
        print(1)
    else:
        print(2)

would print 1, not 2. Although we might say "(6>4) is True" while giving the 
semantics of "if" statement, we _don't_ mean "the object referred by the 
internal name 'True'". We mean the object _externally_ referred by the name 
'True'.

Same as with your "hierarchy question": if you _give_ the explicit list of 
bases, you give it as a list of names. Those names can be rebound and if the 
class definition is executed in such a changed namespace, the bases will 
differ. But you can't rebind anything if you haven't given any explicit base 
names in the first place. It doesn't matter whether a class is "at the top" or 
somewhere else; it matters whether its name is explicitly given.

An illustration: Let's say you have executed

    class A: pass
    class B(A): pass

so now A refers to some class, and B refers to another class, inherited from A. 
If you now execute

    class C(B): pass  # *

you will have a new class C, inherited from B. Of course, if you now change B 
somehow, and then execute (*) again, you will have another class C, inherited 
from changed B - because (*) refers to B explicitly. But if you change _A_ 
somehow, and then execute (*) again, you will have C inherited from the same 
old B - because (*) doesn't refer to A explicitly. As you see, it doesn't 
matter whether A is "on the top" (in fact object is on the top, above A), what 
matters is whether the statement (*) that you re-execute in the changed 
namespace refers to it by name or not.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue31283>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to