How to copy class objects?

matthias.oberlaender at daimlerchrysler.com matthias.oberlaender at daimlerchrysler.com
Mon Feb 12 04:53:06 EST 2001


In <9615nm0sjd at news2.newsguy.com> "Alex Martelli" wrote:
< deleted my stuff>
> 
> new.classobj, followed by setting the __bases__ attribute of the
> new class object to an empty tuple, should do what you're asking.
> 
> Of course, the new class will not inherit anything from anybody,
> since it will have no base classes whatsoever.  Alternatively,
> you can recursively 'copy-class' up the inheritance DAG to
> effect a (somewhat) 'deep-copy' of an entire DAG of related
> classes, if that is what you actually want (not copying a [1]
> class-object, but a whole graph of them).  Similarly, you will
> have to copy (with the copy module, the new module, whatever)
> any object to which class X has references, which you don't
> want Xnew to share -- depending on what those "I don't want
> this to be shared" objects are... it's hard to tell without
> having any idea of the problem you're trying to solve this way
> (e.g., the "not sharing any base classes" item is totally new
> to me here, nor is it fully clear what it implies, as in,
> emptying out the new class's __bases__ vs recursive copies).
> 
> 
> Alex
> 
> 
Ok, here's a more detailed example. I want a stack containing only ints. Then 
I want a stack containing only floats. Extending the pattern to other types 
should be straightforward. Of course, neither should FloatStack be a base 
class of IntStack, nor vice versa. Indeed, new.classobj seems to offer a 
possible solution.

from types import IntType, FloatType

class IntStack:
  """ Stack of int's. Type is checked during push."""
 
  elementType = IntType
  
  def __init__(self):
    self.data = []
    
  def push(self, elem):
    assert type(elem) == self.elementType
    self.data.append(elem)
  
  def pop(self):
    return self.data.pop()
    
# Now let's make a float stack. IntStack serves as a template

from copy import copy
#floatStack = copy(IntStack) # That was my original idea. But, well, it 
doesn't work!

# After a little experimenting I found that I could do it with module 'new' 
like this:
import new

FloatStack = new.classobj("IntStack", IntStack.__bases__, 
IntStack.__dict__.copy()) 

# It is very import do use a copy of IntStack's dictionary.
# If IntStack had base classes, FloatStack would share them. That's ok, since
# we can still edit the __bases__ attribute later.  

FloatStack.__name__ = "FloatStack"
FloatStack.elementType = FloatType
FloatStack.__doc__ = """ Stack of floats's. Type is checked during push."""

print IntStack.__doc__
print FloatStack.__doc__





More information about the Python-list mailing list