473,396 Members | 2,030 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Method returning new instance of class?

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
Jul 18 '05 #1
14 4469
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
Jul 18 '05 #2
"Arthur" <aj******@optonline.com> 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?
Jul 18 '05 #3

"Martin v. Löwis" <ma****@v.loewis.de> wrote in message
news:41***********************@news.freenet.de...
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

Jul 18 '05 #4

"Paul Rubin" <http://ph****@NOSPAM.invalid> wrote in message
news:7x************@ruckus.brouhaha.com...
"Arthur" <aj******@optonline.com> 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
Jul 18 '05 #5
Is this the time to play with __dict__?

Art


I'm afraid -

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

Art
Jul 18 '05 #6
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
Jul 18 '05 #7
Arthur wrote:
"Martin v. L=F6wis" <ma****@v.loewis.de> wrote in message
news:41***********************@news.freenet.de...
=
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
Jul 18 '05 #8

"Jp Calderone" <ex*****@divmod.com> wrote in message
news:ma**************************************@pyth on.org...
Arthur wrote:
"Martin v. L=F6wis" <ma****@v.loewis.de> wrote in message
news:41***********************@news.freenet.de...
=
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
Jul 18 '05 #9

"Arthur" <aj******@optonline.com> wrote in message
news:EM*****************@newsread3.news.atl.earthl 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
Jul 18 '05 #10
Arthur <aj******@optonline.com> wrote:
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.


theclass.__new__(theclass, *args, **kwds)

is one way to return a new instance of class theclass, which will
typically be empty (unless theclass's instances are immutable, since, in
that case, __new__ must do the initializaiton work... because it would
be too late by __init__ time).

Not clear if it's what you need, but it seems to be what you ask for.
Alex
Jul 18 '05 #11
"Martin v. Löwis" <ma****@v.loewis.de> wrote in message news:<41**************@v.loewis.de>...
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.

Back at a high bandwidth connection I decided to try to do some
research to try to reasonably follow what you are telling - despite
the fact that the immediate problem I had been trying to solve seems
to be solved. By using deepcopy(), than overwriting the offending
attributes with fresh instantations.

But both Martin and JP bring copy_reg into the equation in solving
copy issues "by the book".

But the book at:

3.18 copy -- Shallow and deep copy operations (from the 2.3 docs)

says,
on one hand:

"""Classes can use the same interfaces to control copying that they
use to control pickling"""

and on the other:

"""The copy module does not use the copy_reg registration module."""

This is actually pretty esoteric stuff for someone who has not delved
into these mysteries before, so I am a bit lost.

Is it that copy_reg comes into play in defining a custom method for
copying, that is called as a regular method, and not via the copy
module?

Does anyone have a reference for copy_reg used in the specific context
of copying, rather than pickling?

Art
Jul 18 '05 #12
Arthur wrote:
"""The copy module does not use the copy_reg registration module."""

This is actually pretty esoteric stuff for someone who has not delved
into these mysteries before, so I am a bit lost.
It appears that this documentation is incorrect. Just look at the
source of copy.py and see for yourself:

from copy_reg import dispatch_table
....

def copy(x):
...
reductor = dispatch_table.get(cls)
...
Is it that copy_reg comes into play in defining a custom method for
copying, that is called as a regular method, and not via the copy
module?
It is a customization of the copy module.
Does anyone have a reference for copy_reg used in the specific context
of copying, rather than pickling?


Sure: Assume you want to copy file objects, and that this should create
a file object for the same file name and mode, but starting from the
beginning. You do

def copy_file(f):
return file, (f.name, f.mode)
copy_reg.pickle(file, copy_file, file)

Then you can do
f=open("/etc/passwd","r")
f <open file '/etc/passwd', mode 'r' at 0x401f7760> f.readline() 'root:x:0:0:root:/root:/bin/bash\n' g=copy.copy(f)
g <open file '/etc/passwd', mode 'r' at 0x401f7060> g.readline()

'root:x:0:0:root:/root:/bin/bash\n'

Regards,
Martin

Jul 18 '05 #13
"Martin v. Löwis" <ma****@v.loewis.de> wrote:
Arthur wrote:
"""The copy module does not use the copy_reg registration module."""

This is actually pretty esoteric stuff for someone who has not delved
into these mysteries before, so I am a bit lost.


It appears that this documentation is incorrect. Just look at the
source of copy.py and see for yourself:


You're right, of course, but it's hard to reconcile that with the recent
diktat on py-dev that what's in the source doesn't matter -- only what's
documented to work matters (it's in Brett Cannon's python-dev summary of
3 weeks ago, I can find the links from there to the archives if you
wish). Given that peculiar decision, the fact that copy DOES use
copy_reg, in total violation of the docs, looks like it could be taken
away anytime, as a bugfix...

If we want to keep advising people to check the sources, then that
particular python-dev decision must then be reversed; otherwise we
should stop advising using the sources as the ultimate reference... I
don't think we can have it both ways!
Alex
Jul 18 '05 #14
On Tue, 07 Sep 2004 22:29:15 +0200, "Martin v. Löwis"
<ma****@v.loewis.de> wrote:
Arthur wrote:
"""The copy module does not use the copy_reg registration module."""

This is actually pretty esoteric stuff for someone who has not delved
into these mysteries before, so I am a bit lost.
It appears that this documentation is incorrect.


I knew that that was one of the possibilities. On the other hand I
wouldn't have bet much on it. An equally live possiblity was that I
was misunderstanding correct documentation - considering this is all
a bit foggy to me at the moment.

Thanks for making that much clear.
Just look at the
source of copy.py and see for yourself:

from copy_reg import dispatch_table
...

def copy(x):
...
reductor = dispatch_table.get(cls)
...
Is it that copy_reg comes into play in defining a custom method for
copying, that is called as a regular method, and not via the copy
module?


It is a customization of the copy module.
Does anyone have a reference for copy_reg used in the specific context
of copying, rather than pickling?


Sure: Assume you want to copy file objects, and that this should create
a file object for the same file name and mode, but starting from the
beginning. You do

def copy_file(f):
return file, (f.name, f.mode)
copy_reg.pickle(file, copy_file, file)

Then you can do
f=open("/etc/passwd","r")
f<open file '/etc/passwd', mode 'r' at 0x401f7760> f.readline()'root:x:0:0:root:/root:/bin/bash\n' g=copy.copy(f)
g<open file '/etc/passwd', mode 'r' at 0x401f7060> g.readline()

'root:x:0:0:root:/root:/bin/bash\n'


And thanks for that. Which among other things seems to tell me that I
can in fact follow the documentation, and what else I can find, on
copy_reg and pickling pretty much verbatim, when focusing on copying
as my end result. Wasn't sure, among other things, whether the same
copy_reg.pickle(xx) syntax applied to copying application. Aparently
yes.

Art

Jul 18 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Bob Rock | last post by:
Hello, I've got an xml stream that I'd need to deserialize into an instance of a given class A. I'd like to create an instance method on class A (method Deserialize) that takes this XML stream...
18
by: Daniel Gustafsson | last post by:
Hi there, hmm, I've just started with C# and I'm experimenting with method overloading. It seems like it's not possible to override method using return types, only parameters. Is that by design,...
7
by: John Grandy | last post by:
My ASP.NET Web Service project has a Web Method that returns an array filled with instances of a custom class. The custom class is defined in a Class Library that is included in the web-service...
1
by: tony | last post by:
Hello! I just wonder if you out there have any your suggestion about this matter. I have a class in this class I have an ArrayList. In one instance method in this class I fill this ArrayList...
3
by: comp.lang.php | last post by:
class ThumbView extends PaginationView { function ThumbView() {} /** * Determine if the original image is actually an image and thus a thumbnail can be generated at all * * @access public...
9
by: Steve Richter | last post by:
in a generic class, can I code the class so that I can call a static method of the generic class T? In the ConvertFrom method of the generic TypeConvert class I want to write, I have a call to...
5
by: DamienS | last post by:
Hi, I have a static method in a class and I need to be able to return a reference to "this". Googling around, I found a heap of discussions of the pros/cons of "abstract static" etc. It was...
4
by: crazychimp132 | last post by:
Greetings. I am looking for a way to achieve method behavior for a class I created. That is, it has a __call__ method, so can be called like a function. But I also want it to be treated as a...
0
by: Gabriel Genellina | last post by:
En Tue, 29 Jul 2008 08:45:02 -0300, Themis Bourdenas <bourdenas@gmail.com> escribi�: In a very strict sense, I'd say that all those references to "method decorators" are wrong - because...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.