I agree it that the Persistent.__deecopy__ thing does smell like misuse on my
part. However I'd be happy to hear any alternative suggestion you have on how
to solve the problem I have.
Meanwhile, I thought of a nice backwards-compatible way to implement what I
suggest, but I want to know whether this idea makes sense at all to the people
here.
Ram.
Deepcopy is a very simple operation conceptually, there's no need to
make it more complicated. How about implementing __deepcopy__ in your
world state objects? Specify attributes that don't need copying. You
can even use the Persistent class to signal that. Something like this
(untested!):
def __deepcopy__(self):
new = self.__class__()
for k,v in self.__dict__.iteritems():
setattr(new, k, v if isinstance(v, Persistent) else deepcopy(v))
return new
Vitor
It is already quite easy to abuse the "memo" dict argument of
copy.deepcopy to pass this kind of flag to the __deepcopy__ methods.
What else do you need?
- Jacob
And what happens when State refers to another object which refers to a
Persistent?
Ram.
Then that object would need to implement the same method, perhaps by
inheriting form a common base. The point is that it can be done in a
straightforward manner without needing to change the stdlib.
Vitor
And what if the object is from a class defined by a third-party module that I
can't change?
> The point is that it can be done in a
> straightforward manner without needing to change the stdlib.
I guess so, yes. My method would be something like what Jacob said, abusing
the memo dict to pass the copying mode. But I thought perhaps we can set a
standard way for specifying different copy modes, because otherwise I'll do my
memo hack and someone else will do his different memo hack and it won't be
compatible.
I'll detail my hack later today when I'll be back home.
Ram.
Perhaps you can post a recipe at the Python Cookbook. People who care
about compatibility can follow the same recipe.
Alternatively, this use case strikes me as being rather similar to the
various flatten() recipes out there that accept a list of "atomic" types
to avoid flattening iterable-but-not-really-a-container types such as
strings.
The analogy currently breaks due to copy.deepcopy() being set up with
each __deepcopy__ method doing its own recursion rather than
constructing a graph of mutable (to be copied) and immutable members (to
be referenced) down the chain of the object graph.
More flexible (but significantly harder) than adding a copy mode would
be defining a protocol for exposing the object graph in a standardised
fashion.
__iter__ in conjunction with __dict__ would get you a fair way, but
there would be a lot of complications.
Cheers,
Nick.
--
Nick Coghlan | ncog...@gmail.com | Brisbane, Australia
---------------------------------------------------------------
> With the __deepcopy__ method, user-defined objects can specify how they
> will be copied. But it is assumed that you will always want to copy them
> the same way. What if sometimes you want to copy them in one way and
> sometimes in another?
Then you need to define your own system of copying methods
and implement them appropriately for the classes they apply
to.
The deepcopy mechanism is only designed to cover simple
cases. It isn't, and can't be, all things to all people.
--
Greg
(Just a closing comment about this: I tried this and it was really pretty
simple, just making a dict subclass.)
Ram.