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