On 01/12/2015 02:35 PM, Chris Angelico wrote:
On Tue, Jan 13, 2015 at 9:27 AM, Andrew Robinson
<andr...@r3dsolutions.com> wrote:
Huh? I'm not adding any values when I merely subclass bool ; and even if the
subclass could be instantiated -- that's doesn't mean a new value or
instance of the base class (bool) must exist.  For I could happily work with
a new subclass that contains no new data, but only an already existing
instance of 'True' or 'False' as its value source.   That means there is no
new value...  but at most (and even that could be worked around) a new
instance of a subclass containing an existing instance of it's base class.
Hmmm....
That may be true in python, as it is now, but that doesn't mean that Guido had to leave it that way when he decided to change the language to single out bool, and make it's subclassing rules abnormal in the first place.
He was changing the language when he made the decision after all !!

What I am wanting to know is WHY did Guido think it so important to do that ? Why was he so focused on a strict inability to have any instances of a bool subclass at all -- that he made a very arbitrary exception to the general rule that base types in Python can be subclassed ?

There's no reason in object oriented programming principles in general that requires a new subclass instance to be a COMPLETELY DISTINCT instance from an already existing superclass instance.... nor, have I ever seen Guido say that Python is designed intentionally to force this to always be the case... so I'm not sure that's its anything more than a non guaranteed implementation detail that Python acts the way you say it does....

I don't see, within Python, an intrinsic reason (other than lack of support/foresight in the historical evolution of Python to date), as to why a subclass couldn't be instanted with the data coming from an *already* existing instance of it's superclass.

There is no need to copy data from an initialized superclass instance into a subclass instance that has no new data, but only rebind -- or add a binding/proxy object -- to bind the superclass instance to the subclass methods.

eg: what is now standard practice to create a new copy of the superclass:

class myFalse( bool ): __new__( self, data ): return super( myFalse, self ).__new__(self,data)

Could be replaced by a general purpose proxy meant to handle singleton subclassing:

class myFalse( bool ): __new__( self ): return bind_superinstance_to_subclass( False, myFalse )

he Python bool type has the following
invariant, for any object x:

assert not isinstance(x, bool) or x is True or x is False
Really !???
Where, in the language definition, did Guido explicitly guarantee this invariant ?

(You can fiddle with this in Py2 by rebinding the names True and
False, but you could replace those names with (1==1) and (1==0) if you
want to be completely safe. Likewise, the name "bool" could be
replaced with (1==1).__class__ to avoid any stupidities there. But
conceptually, that's the invariant.)
Interesting ... but rebinding True and False, won't extend the new capabilities to modules which are imported. They will still, I think, be bound to the old True and False values. I know, for example -- I can redefine the class bool altogether; although the type string becomes 'main.bool' -- none the less, it does not exist in default scope when I switch namespaces; eg: in a module being imported 'bool' still means the old version of class bool.

I have to do something more drastic, like __builtins__.bool = class bool(int): ... And then, even modules will recognize the changed class definition.

Hmmm.....
>>> __builtins__.True='yes'
>>> True
'yes'

However, such actions -- I think -- are rather drastic; because they produce situations where another third party library in competition with mine might also have need of subclassing 'bool' and then we are in a fight for a static binding name with winner takes all ... rather than sharing dynamically compatible definitions based on subclasses.

Subclassing bool breaks this invariant, unless you never instantiate
the subclass, in which case it's completely useless.

Well we can't subclass bool now -- and the language would have to change in order for us to be able to subclass it; So -- I don't think your assert statement guarantees anything if case the language changes... On the other hand, I also don't see that your assert statement would ever return False even as it is written --- even if the object (x) was sub-classed or a totally different object than True or False .... and so I *definitely* don't see why your assert statement would Fail if the language changed in one of several subtle ways I think it could.

I mean, even right now -- with the language as-is -- let's define something that blatantly creates a new instance of something neither an actual instance of True nor False, and make that x -- and see if your assertion catches it:

Python 2.7.5 (default, May 29 2013, 02:28:51)
[GCC 4.8.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x=(False,)
>>> assert not isinstance(x, bool) or x is True or x is False
>>>

LOL ... no exception was raised... and we know if the assertion Failed, an exception ought to be raised:

>>> assert False
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError
>>>

And I'll prove my object is neither the instance True nor False itself, but a tupple wrap of it:

>>> (False,)==False
False
>>>

So -- your assertion, at least as shown, is pretty useless in helping determine why subclassing is not allowed, or instances of subclasses that are not distinct from their superclasses existing instance.



--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to