Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Method returning new instance of class?

Reply
Thread Tools

Method returning new instance of class?

 
 
Arthur
Guest
Posts: n/a
 
      09-04-2004
A bit inspired by the decorator discussions, I'm trying to tackle something
I had been avoiding.

Essentially I am trying to create a non-destructive tranformation of an
instance of a class - is one way of putting it.

The way I am currently conceptualizing a solution, what I need is a method
of the class that returns a new instance of the class.

I'm sure this is not new territory.

Suggestions appreciated.

Art


 
Reply With Quote
 
 
 
 
=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=
Guest
Posts: n/a
 
      09-04-2004
Arthur wrote:
> Essentially I am trying to create a non-destructive tranformation of an
> instance of a class - is one way of putting it.
>
> The way I am currently conceptualizing a solution, what I need is a method
> of the class that returns a new instance of the class.


So you want a copy of the object. I'd use copy.copy for this, perhaps
copy.deepcopy.

Regards,
Martin
 
Reply With Quote
 
 
 
 
Paul Rubin
Guest
Posts: n/a
 
      09-04-2004
"Arthur" <(E-Mail Removed)> writes:
> The way I am currently conceptualizing a solution, what I need is a method
> of the class that returns a new instance of the class.


class foo:
def bar(self):
return foo()

What's the problem?
 
Reply With Quote
 
Arthur
Guest
Posts: n/a
 
      09-04-2004

"Martin v. L÷wis" <(E-Mail Removed)> wrote in message
news:4139a87a$0$30204$(E-Mail Removed)...
> Arthur wrote:
> > Essentially I am trying to create a non-destructive tranformation of an
> > instance of a class - is one way of putting it.
> >
> > The way I am currently conceptualizing a solution, what I need is a

method
> > of the class that returns a new instance of the class.

>
> So you want a copy of the object. I'd use copy.copy for this, perhaps
> copy.deepcopy.


That was my first instinct. And perhaps my problem is in here somewhere.

The app is graphical, and I use a Python extensions in C++ using the Boost
library (vpython, new version). My class instance has an attribute which is
a vpython object. Copy.copy doesn't get me where I need to be because my new
instance gets a reference to the same vpython object, and changes to it are
reflected in the original instance. Copy.deepcopy doesn't work for more
obscure reasons. I get an error message generating up from vpython when I
try to change an attribute of the object on the new instance - though I am
interacting with it in the same manner that works fine when performed on the
original instance.

But do you see any reason why this might be?

If it sounds totally illogical, I'll go back and check myself - because of
course the actual sitruation is a bit more complicated than what I am
describing, and I guess it is possible I am falling off the ledge somewhere
else.

Art
>
> Regards,
> Martin



 
Reply With Quote
 
Arthur
Guest
Posts: n/a
 
      09-04-2004

"Paul Rubin" <http://(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> "Arthur" <(E-Mail Removed)> writes:
> > The way I am currently conceptualizing a solution, what I need is a

method
> > of the class that returns a new instance of the class.

>
> class foo:
> def bar(self):
> return foo()
>
> What's the problem?


As I responded to Martin, what I am looking for - though I didn't describe
it well - is a copy of the original instance (with, for example, same
version of attributes generated with reference to its original arguments).

And I am trying to work around something - or diagnose something I am
running into - using copy.deepcopy.

Is this the time to play with __dict__?

Art


 
Reply With Quote
 
Arthur
Guest
Posts: n/a
 
      09-04-2004

> Is this the time to play with __dict__?
>
> Art


I'm afraid -

That didn't come out very elegant;ly, did it

Art


 
Reply With Quote
 
=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=
Guest
Posts: n/a
 
      09-04-2004
Arthur wrote:
> The app is graphical, and I use a Python extensions in C++ using the Boost
> library (vpython, new version). My class instance has an attribute which is
> a vpython object. Copy.copy doesn't get me where I need to be because my new
> instance gets a reference to the same vpython object, and changes to it are
> reflected in the original instance.

[...]
>
> But do you see any reason why this might be?


Certainly. copy.copy expects that each object follows a certain protocol
for copying. Copying of certain types (including all classic classes)
is build into copy.py. For newstyle classes and all other types, copying
procedures must be registered with copy_reg. If a type is not registered
with copy_reg, as a last fall back, the __reduce_ex__ and __reduce__
functions are invoked for the type. If not specifically overridden, they
always return the original object.

Regards,
Martin
 
Reply With Quote
 
Jp Calderone
Guest
Posts: n/a
 
      09-04-2004
Arthur wrote:
> "Martin v. L=F6wis" <(E-Mail Removed)> wrote in message
> news:4139a87a$0$30204$(E-Mail Removed)...
> =


>>Arthur wrote:
>>
>>>Essentially I am trying to create a non-destructive tranformation of an
>>>instance of a class - is one way of putting it.
>>>
>>>The way I am currently conceptualizing a solution, what I need is a

> =


> method
> =


>>>of the class that returns a new instance of the class.

>>
>>So you want a copy of the object. I'd use copy.copy for this, perhaps
>>copy.deepcopy.

> =


> =


> That was my first instinct. And perhaps my problem is in here somewhere.
> =


> The app is graphical, and I use a Python extensions in C++ using the Boost
> library (vpython, new version). My class instance has an attribute which=

is
> a vpython object. Copy.copy doesn't get me where I need to be because my =

new
> instance gets a reference to the same vpython object, and changes to it a=

re
> reflected in the original instance. Copy.deepcopy doesn't work for more
> obscure reasons. I get an error message generating up from vpython when I
> try to change an attribute of the object on the new instance - though I =

am
> interacting with it in the same manner that works fine when performed on =

the
> original instance.
> =


> But do you see any reason why this might be?
> =


> If it sounds totally illogical, I'll go back and check myself - because of
> course the actual sitruation is a bit more complicated than what I am
> describing, and I guess it is possible I am falling off the ledge somewhe=

re
> else.


It sounds terribly logical. Copying objects is extremely difficult =

to do correctly. There is no way to do it generically and correctly. =

Make the copy too shallow, and you get unwanted shared state. Make the =

copy too deep and the new object is useless. How do you decide how deep =

is deep enough? You can't, at least not without intimate knowledge of =

the object you're dealing with.

Once you figure out exactly how deep you need to make your copy, you =

can tell copy.deepcopy() how to behave with the copy_reg module. Of =

course, since this knowledge is quite closely tied to VPython, it should =

really be *part* of the VPython package, so that changes to the =

internals of VPython can be made right alongside changes to the code =

which knows how to copy its objects.

Jp
 
Reply With Quote
 
Arthur
Guest
Posts: n/a
 
      09-05-2004

"Jp Calderone" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Arthur wrote:
> > "Martin v. L=F6wis" <(E-Mail Removed)> wrote in message
> > news:4139a87a$0$30204$(E-Mail Removed)...
> > =
>>Copy.deepcopy doesn't work for more
> > obscure reasons. I get an error message generating up from vpython when

I
> > try to change an attribute of the object on the new instance - though I

=
> am
> > interacting with it in the same manner that works fine when performed on

=
> the
> > original instance.
> > =

>
> > But do you see any reason why this might be?
> > =

> It sounds terribly logical. Copying objects is extremely difficult =
>
> to do correctly. There is no way to do it generically and correctly. =
>
> Make the copy too shallow, and you get unwanted shared state. Make the =
>
> copy too deep and the new object is useless. How do you decide how deep =
>
> is deep enough? You can't, at least not without intimate knowledge of =
>
> the object you're dealing with.
>
> Once you figure out exactly how deep you need to make your copy, you =
>
> can tell copy.deepcopy() how to behave with the copy_reg module. Of =
>
> course, since this knowledge is quite closely tied to VPython, it should =
>
> really be *part* of the VPython package, so that changes to the =
>
> internals of VPython can be made right alongside changes to the code =
>
> which knows how to copy its objects.



Well a quick look at copy_reg and I backed away. Particularly since I am
accessing the internet from a dial-up at the moment and am not in a position
to do the research necessary to get a handle on it. The module docs are
much too sketchy here for someone starting with this from where I am
starting. And as you say, there looked like I might need to get at VPython
internals to do it correctly.

However I did realize, in reading the docs, that overriding __copy__ might
be all I needed to do. Really what I was looking for was a copy of the
original instance with a fresh VPython object on which to operate.
Conceptually I am doing a non-destructive transformation of the instance,
with the transformed object the same, exscept at a transformed location.
Something like this seemed to work:

def __copy__(self):
newcopy=copy.deepcopy(self)
newcopy.vpythonobject=<intialize new vpython object here>
return newcopy

But before getting too far into testing whether this accomplished the copy I
was looking for (perhaps the success was more apparent than real, and the
advice to resort to copy_reg is more unavoidable than I understand) I
realized that I had misconceived something more fundamental. That the
normal instance creation process involves registerting the new instance with
the app in various ways, and that a copy won't accomplish this.

That is until wrote the last paragraph, and realized that I might be able to
throw the registration routines into the __copy__ method.

Hmmm.

Let's try.

Art


 
Reply With Quote
 
Arthur
Guest
Posts: n/a
 
      09-05-2004

"Arthur" <(E-Mail Removed)> wrote in message
news:EMD_c.7014$(E-Mail Removed) ink.net...
>
> Something like this seemed to work:
>
> def __copy__(self):
> newcopy=copy.deepcopy(self)
> newcopy.vpythonobject=<intialize new vpython object here>
> return newcopy
>
> But before getting too far into testing whether this accomplished the copy

I
> was looking for (perhaps the success was more apparent than real, and the
> advice to resort to copy_reg is more unavoidable than I understand) I
> realized that I had misconceived something more fundamental. That the
> normal instance creation process involves registerting the new instance

with
> the app in various ways, and that a copy won't accomplish this.
>
> That is until wrote the last paragraph, and realized that I might be able

to
> throw the registration routines into the __copy__ method.
>
> Hmmm.
>
> Let's try.


With the further realization that I wasn't buying myself anything in
particular by overriding __copy__ at this stage, but that some function
starting with a deepcopy and then reassigning some of the attributes derived
from VPython (which luckily are the attributes that I want as fresh for what
I am trying to do), then running through the "registration" routines
normally done on __init__, then returning the manipulated deepcopy - I seem
to be home.

Now on to the functionality I had in mind, given this capability.

Which should be fun.

Art


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
why can't an instance instantiated within a class method access aprotected instance method? Greg Hauptmann Ruby 9 06-16-2008 10:16 AM
instance method adding another instance method to the class Raj Singh Ruby 2 05-29-2008 10:09 PM
TypeError: unbound method PrintInput() must be called with test instance as first argument (got test instance instead) arotem Python 4 10-17-2005 07:52 AM
Generics: factory method for returning parameterized instance allen@rrsg.ee.uct.ac.za Java 3 09-17-2005 07:16 AM
Cannot refer to an instance member of a class from within a shared method or shared member initializer without an explicit instance of the class. DJ Dev ASP .Net 3 02-08-2004 04:19 PM



Advertisments