Copy constructors

Guido van Rossum guido at python.org
Sat Aug 11 21:35:16 EDT 2001


Glyph Lefkowitz <glyph at twistedmatrix.com> writes:

> Am I correct in understanding from this thread that there is an intent to
> remove the ability to assign an instance's __class__ attribute?

Yes, I'd like to remove this.  See my previous post in this thread for
more of an explanation of the problem.  But I haven't decided yet!
This thread will help me figure out how big of a deal it will be.

Also note that nothing will change (yet) for classic classes -- in
2.2, classic classes will use a different metaclass from "new-style"
classes, and the classic metaclass will provide the same semantics
for classes and instance as before.  The class statement creates a
classic class by default -- unless you explicitly subclass from a
built-in type or a new-style class.

In a sense, in 2.2 the new-style classes will still be experimental,
and it's quite likely that based upon feedback from users they will
change (for the better) in later versions.

> > Let's just say that use of this feature is at your own risk.  It was
> > an experiment.  I *could* restore it partially (see below) but I'd
> > rather not, given that better alternatives are available.
> 
> Are there any features that we can use any longer that are not 'at our own
> risk'?  Division will be changed, __class__ assignment is going away,
> type() means something different, even the rules of scope...

But you're getting so much in return!  Subclassing built-in types,
get/set methods, class and static methods, uniform introspection...

> Also, as far as I know, better alternatives do not exist; for example,
> "promise" objects from a database which are latently initialized when they
> are accessed.

If you know the type it's going to be eventually, you can use
C.__new__() to create an uninitialized C instance.

> One module that I use *all the time*;
> twisted.python.rebuild.rebuild, is based entirely upon this "trick".

I guess the name ("twisted") says it all. :-)

> One
> of the eye-popping cool features of Python is the ability to change code
> and have existing instances update to use the new methods automatically.

You will still be able to modify *classes* dynamically -- although you
have to declare this option by putting __dynamic__ = 1 in your class
statement.

> Smalltalk's Object>>become: is highly useful for similiar reasons; is
> there a new way to emulate this without __class__ assignment?

Probably not -- although I don't know what that does.

> > I'm sure I'd be able to come up with some kind of check that works. It
> > would probably be very similar to the check I already use to determine
> > whether two base classes are compatible -- the check that stops you
> > from doing "class C(list, dictionary)".  But I repeat: I'd rather not.
> 
> Is there a discussion somewhere of why you'd rather not?  This is
> *essential* functionality for me, especially since it sounds like it won't
> be able to be completely replicated through some other mechanism.

I'd rather not because it's a complicated check to write, and it may
be difficult to explain the restrictions.  Here's an example of the
kind of restriction that is unavoidable.

I don't know how familiar you are with Python's C-level internals.  If
you are, you'll appreciate the problem if I took a list object and
changed its type pointer to the dictionary type -- the instance
lay-out of a dictionary is different, and all the methods would be
using the list data as if it were dictionary data.  Recipe for
disaster.  Likewise, changing a featureless object into a list or dict
would at the very least require growing the size of the instance; this
would require a realloc(), which may move the object in memory.  But
if there are other references to the object, these would all have to
be updated.  Python's run-time architecture just doesn't support that.

> (If you implement "reference.become(other)", for example, I won't
> mind nearly so much <0.5 wink>)

I'm not sure what that means, but if you could live with weak
references, we could easily add a way to change the referent of a weak
reference object.

> > That depends on how much of a slowdown it is. :)
> 
> I don't know about others who use this feature, but the way I use it I
> could afford to wait 0.5 seconds for each __class__ assignment and not be
> too upset about it.  Losing this ability entirely, however, would remove a
> significant feature from Twisted when used with a later python version.  
> I implore you not to remove it.

Understood.  Nevertheless, all evidence suggests that Twisted is not
typical Python code. :-)

I guess I have a bit of a hidden agenda: Python is more dynamic than
the language I *wanted* to design.  Some of the dynamicism was simply
a implementation trick.  Some of the dynamicism is getting in the way
of optimizing code, because the optimizer can never prove that certain
variables won't be changed.  So I'm trying to look for ways that pin
down things a bit more.  I'm making assumptions about how "typical"
Python code uses the dynamic features, and I'm slowly trying to
introduce restrictions in the language that make the optimizer's life
easier without affecting "typical" code.

For example, we're looking into optimizing access to builtins.  For
this, we need to assume that the __builtin__ module is immutable; in
addition, if a module doesn't have a global 'len', for example, we
have to assume that such a global won't be inserted into the module
dynamically.  I'm only aware of a very small number of applications
that violate this constraint; I'd rather provide a separate explicit
mechanism to override built-in functions so that the optimizer can be
aware of a potential change and avoid it.

--Guido van Rossum (home page: http://www.python.org/~guido/)



More information about the Python-list mailing list