473,385 Members | 1,535 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,385 software developers and data experts.

Question about references/copies

I'm using Python only for some months now and I'm wondering, whether such
assignments as above are creating bitwise copies of an object or just
recieve a reference. That means I wanted to know, wheter Python in general
differs between references and copies:

class someclass:
def __init__( self, otherobject):
self.someattribute = otherobject

And my second question is, whether I should use a cast in such cases or
not (I know, a cast isn't mandatory here...)

Thanks a lot!
Jul 18 '05 #1
9 1661
On Sat, 28 Aug 2004 09:52:36 +0200, Henning Kage <c0***@gmx.de> wrote:
I'm using Python only for some months now and I'm wondering, whether such
assignments as above are creating bitwise copies of an object or just
recieve a reference. That means I wanted to know, wheter Python in general
differs between references and copies:
It's all references. If you want a copy, use the copy module.
class someclass:
def __init__( self, otherobject):
self.someattribute = otherobject

And my second question is, whether I should use a cast in such cases or
not (I know, a cast isn't mandatory here...)


A cast? Python has no static typing, so I'm unsure how or why you'd do a cast.
Jul 18 '05 #2
Am Sat, 28 Aug 2004 18:11:46 +1000 schrieb Anthony Baxter:
It's all references. If you want a copy, use the copy module.
Ok, thanks.
A cast? Python has no static typing, so I'm unsure how or why you'd do a cast.


As I said, I'm new to Python and as other languages do support such casts
(as I know, in C# e.g. you have to do such casts if you are iterating
over array lists and have to access the stored objects), I thought of it
in Python too.

Jul 18 '05 #3
Henning Kage <c0***@gmx.de> wrote:
I'm using Python only for some months now and I'm wondering, whether such
assignments as above
"As above" _where_?
are creating bitwise copies of an object or just
recieve a reference. That means I wanted to know, wheter Python in general
differs between references and copies:

class someclass:
def __init__( self, otherobject):
self.someattribute = otherobject
Python makes no copy unless you explicitly ask for a copy -- what you
get is always a reference. There are several ways to ask for copies --
the most general and powerful ones you'll find in standard library
modules copy (both copy.copy and copy.deepcopy -- all other ways of
asking for a copy, except copy.deepcopy, get shallow copies).

The only area where one might have some doubt is _slicing_. When you
code x=y[z:t] you're getting a (shallow) copy, if y belongs to any of
the builtin types that implement slicing, BUT there are important
third-party extensions whose types behave differently -- specifically,
Numeric; if the type of y is Numeric.array, then x shares (some of) the
data of y.

So we can say that Python _allows_ third-party and user-coded types with
slicing that works by data sharing, even though the preferred semantics
of slicing is by (shallow) copy.

And my second question is, whether I should use a cast in such cases or
not (I know, a cast isn't mandatory here...)


Python does not really have the concept of a cast. Something that looks
like a cast to you is probably one of the ways to ask for a copy: for
example, if x is a list, list(x) is a (shallow) copy of x -- if y is a
dict, dict(y) is a (shallow) copy of y, and so on.

If you take an argument X that is of any iterable type, and you need to
perform local operations on the items of X (which will not risk altering
the original value of X), it is quite common to start with something
like:
X = list(X)
if X was already a list this makes a copy (so the original does not get
altered); if X was, say, a tuple, an open file, a dict, a string, ...,
in other words any bound iterable, this in any case ensures X is now a
list with that iterable's items (be careful: some iterables change state
when iterated upon -- if X was a file, that file object is now at
end-of-file, and the caller may need, if feasible, to call its method
seek to get that file back to the previous state, for example -- so the
"will not risk altering" tidbit above does need qualification).

So anyway you might now call such mutator methods on X as sort, reverse,
extend, pop -- all the nice methods that list offers and other iterable
types don't -- and in the end presumably return or store some result
based on the suitably-mutated X.

Another similar operation that you may do reasonably frequently as your
familiarity with Python grows is to ensure you have an _iterator_ for a
generically _iterable_ argument, and sometimes the best way is something
like:
X = iter(X)
you don't get many methods in X this way (basically, only X.next...) but
you do ensure that X "keeps state" that tracks its current iteration.
Note a big difference here: if X is already an iterator, iter(X) will
NOT make a copy -- it wll return a reference to X unchanged. An example
generator using this technique:

def interleave(X, Y):
X = iter(X)
Y = iter(Y)
while True:
yield X.next()
yield Y.next()

not necessarily the absolute best approach, but pretty clear -- and the
calls to iter are indispensable here, in case X and/or Y as originally
passed were iterABLES that are not iterATORS such as lists etc.
Alex
Jul 18 '05 #4

"Henning Kage" <c0***@gmx.de> wrote in message
news:pa****************************@gmx.de...
I'm using Python only for some months now and I'm wondering, whether such
assignments as above are creating bitwise copies of an object or just
recieve a reference. That means I wanted to know, wheter Python in
general
differs between references and copies:


Better to think of Python this way: it has objects and bindings of objects
to one or more targets (names and slots of composite objects). Binding
statements (target = expression) always and only assign targets to objects.

Terry J. Reedy

Jul 18 '05 #5
Terry Reedy <tj*****@udel.edu> wrote:
"Henning Kage" <c0***@gmx.de> wrote in message
news:pa****************************@gmx.de...
I'm using Python only for some months now and I'm wondering, whether such
assignments as above are creating bitwise copies of an object or just
recieve a reference. That means I wanted to know, wheter Python in
general
differs between references and copies:


Better to think of Python this way: it has objects and bindings of objects
to one or more targets (names and slots of composite objects). Binding
statements (target = expression) always and only assign targets to objects.


Yes, the binding per se never does anything more, if it is to a bare
name (if it's to an indexing, a slicing, or an attribute reference aka a
dotted name, things can become more interesting sometimes). And
normally the expression itself makes no copies unless copies are
specifically requested in it. Slicing though is the interesting part.

Slicing always creates a new object (except that whole-object slicing of
an immutable sliceable need not). But the interesting issue is with the
TARGETS, the SLOTS, inside that new object. Are they the SAME slots as
in the object being sliced? If said object is a list or instance of
array.array -- no, the slots are new and separate ones.

E.g., consider:
z = []
a = [ z, z, 23 ]
sys.getrefcount(z) 4 b = a[:]
sys.getrefcount(z) 6

Here, slicing does create three new slots, two of which are additional
references to the same list object z refers to. However:
z = []
a = Numeric.zeros((3,), 'O')
a[0]=a[1]=z
sys.getrefcount(z) 4 b = a[:]
sys.getrefcount(z)

4

Here, slicing "shares" the SAME slots that 'a' already had, so there is
no change in the reference count of the list object z refers to.
Alex

Jul 18 '05 #6
On Sat, 28 Aug 2004 11:32:39 +0200, al*****@yahoo.com (Alex Martelli)
wrote:
Henning Kage <c0***@gmx.de> wrote:
I'm using Python only for some months now and I'm wondering, whether such
assignments as above


"As above" _where_?
are creating bitwise copies of an object or just
recieve a reference. That means I wanted to know, wheter Python in general
differs between references and copies:

class someclass:
def __init__( self, otherobject):
self.someattribute = otherobject


Python makes no copy unless you explicitly ask for a copy -- what you
get is always a reference. There are several ways to ask for copies --
the most general and powerful ones you'll find in standard library
modules copy (both copy.copy and copy.deepcopy -- all other ways of
asking for a copy, except copy.deepcopy, get shallow copies).


I've felt strongly that this key piece of Python learning would be
and much, much more inevitable if there was a (preferred) consistent
way to ask for a copy, across objects - and/or that the copy module
was something other than one of XXX importable moudles.

That dicts and lists (for example) have totally different syntax for
copy, helps - I promise - to misdirect and confuse. I happen to
consider this entire area a significant wart. I think I am entitled to
consider it so.

I had tried to bring this up to in various forums, most particularly
edu-sig - where I thought this knid of discussion might be of
particular significance - and was rather rudely asked by Guido to take
it elsewhere. Where? not clear.

Ray Hettinger asked Gudio for permission to at least put a few words
about the copy module in the tutorial section mentioning a few of the
key importable modules - to at least, I think,. give new users a clue
that there was something of conceptual significance in all this. And
was refused.

My only participation on python-dev was to ask Gudio to reconsider

And was - rudely - dismissed.

I promise Brett C. and Anthony B. that there is more of a 2-way
street than they might think. For some of us trying to make our own
kind of contribution in our own kind of way.

Art

Jul 18 '05 #7
Arthur <aj******@optonline.com> wrote:
...
I've felt strongly that this key piece of Python learning would be
and much, much more inevitable if there was a (preferred) consistent
way to ask for a copy, across objects -
There is: type(obj)(obj) is (almost) always the best way to get a
(shallow) copy of copyable objects (won't work with noncopyables such as
files and other iterators, of course) of built-in types (whether
user-coded types support that popular convention is of course another
issue -- it depend on the author of each of these types).

If you know what type obj is, say a list; or, if don't really care
whether obj is (say) a list or a tuple or ... 'cause what you want is a
list anyway, then the normal way to spell this is of course list(obj).
and/or that the copy module
was something other than one of XXX importable moudles.
Well, it's Python-coded, so it seems quite natural to me that it be a
perfectly normal importable module.

That dicts and lists (for example) have totally different syntax for
copy, helps - I promise - to misdirect and confuse. I happen to
dict(mydict) and list(mylist) appear quite similar to me. Sure,
mydict.copy() has stuck around from the dark ages and won't be even
considered for removal, due to backwards compatibility, until Python 3.0
some years from now; and mylist[:] also builds a shallow copy; but
despite their undeserved popularity these are not "the syntax for copy"
in my book, any more than, say, dict(mydict.iteritems()) for a dict or
[x for x in mylist] for a list, even though THOSE happen to make shallow
copies too (and I HAVE seen them used in code intended as "serious").
consider this entire area a significant wart. I think I am entitled to
consider it so.
Given the apparent dearth of information in the matter, you may be
right. I'll do my best to keep clarifying my viewpoint in my books...
I had tried to bring this up to in various forums, most particularly
edu-sig - where I thought this knid of discussion might be of
particular significance - and was rather rudely asked by Guido to take
it elsewhere. Where? not clear.


Not sure why edu-sig would be more appropriate than any generic Python
forum, actually. But not particularly inappropriate either, I think.
Alex
Jul 18 '05 #8
On Sat, 28 Aug 2004 16:02:59 +0200, al*****@yahoo.com (Alex Martelli)
wrote:
Arthur <aj******@optonline.com> wrote:
...
I've felt strongly that this key piece of Python learning would be
and much, much more inevitable if there was a (preferred) consistent
way to ask for a copy, across objects -
There is: type(obj)(obj) is (almost) always the best way to get a
(shallow) copy of copyable objects (won't work with noncopyables such as
files and other iterators, of course) of built-in types (whether
user-coded types support that popular convention is of course another
issue -- it depend on the author of each of these types).

If you know what type obj is, say a list; or, if don't really care
whether obj is (say) a list or a tuple or ... 'cause what you want is a
list anyway, then the normal way to spell this is of course list(obj).
Well there is a lot of divergence in practice, as I think you know.
And beyond that no real consensus on what is preferable, as far as I
have been able to determnine Though hearing Alex declare it as
preferable is the beginning of the formation of some consensus, one
hopes.
and/or that the copy module
was something other than one of XXX importable moudles.
Well, it's Python-coded, so it seems quite natural to me that it be a
perfectly normal importable module.


I understand, now, the problems with treating the copy module
otherwise than it is. But it is a strange duck - conceptually in the
middle of things, but with limited functional importance. I thought
only that Ray's idea of setting it off a bit, by mention in the
tutorial, had considerable merit.
That dicts and lists (for example) have totally different syntax for
copy, helps - I promise - to misdirect and confuse. I happen to
dict(mydict) and list(mylist) appear quite similar to me. Sure,
mydict.copy() has stuck around from the dark ages and won't be even
considered for removal, due to backwards compatibility, until Python 3.0
some years from now; and mylist[:] also builds a shallow copy; but
despite their undeserved popularity these are not "the syntax for copy"
in my book, any more than, say, dict(mydict.iteritems()) for a dict or
[x for x in mylist] for a list, even though THOSE happen to make shallow
copies too (and I HAVE seen them used in code intended as "serious").


I agree that dict(mydict) and list(mylist) - it that is what one saw
with consitentcy in practice - would go a long way. I'll try to
practice it, having gotten into the list[:] habit.

And ...

It was my understanding - perhaps wrong - that dict.copy() was an
add-on method to dict of non-ancient origin. How do I check?
consider this entire area a significant wart. I think I am entitled to
consider it so.


Given the apparent dearth of information in the matter, you may be
right. I'll do my best to keep clarifying my viewpoint in my books...


That would be excellant!

ARt
Jul 18 '05 #9
Arthur <aj******@optonline.com> wrote:
...
If you know what type obj is, say a list; or, if don't really care
whether obj is (say) a list or a tuple or ... 'cause what you want is a
list anyway, then the normal way to spell this is of course list(obj).
Well there is a lot of divergence in practice, as I think you know.


Sure, I did say I've seen [x for x in thelist] used.
And beyond that no real consensus on what is preferable, as far as I
Hmmm -- I've never seen a debate trying to determine that consensus,
actually.
have been able to determnine Though hearing Alex declare it as
preferable is the beginning of the formation of some consensus, one
hopes.
You're very kind, but I've hardly ever been able to convince GvR of
anything whatsoever;-)

and/or that the copy module
was something other than one of XXX importable moudles.


Well, it's Python-coded, so it seems quite natural to me that it be a
perfectly normal importable module.


I understand, now, the problems with treating the copy module
otherwise than it is. But it is a strange duck - conceptually in the
middle of things, but with limited functional importance. I thought


Yes, I see your point. Anna and I just co-wrote a Cookbook recipe about
copying, so we ended up debating several such points and she also
brought this one up, btw
only that Ray's idea of setting it off a bit, by mention in the
tutorial, had considerable merit.
Yep, I see that it might.
I agree that dict(mydict) and list(mylist) - it that is what one saw
with consitentcy in practice - would go a long way. I'll try to
practice it, having gotten into the list[:] habit.
myseq[:] has the advantage of being polymorphic over list, tuple, str,
and array.array -- list(myseq) would produce a new list no matter what
the type of myseq (it's more polymorphic too, which is generally fine
but may perhaps hide problems if myseq is, say, a dict, unexpectedly
turning it into a sequence of its keys in arbitrary hash order). I find
that when people are copying a dubious-type sequence they're often happy
with getting a list anyway (so they KNOW they can use list's wide
variety of methods), the only trouble case being indeed list(somedict).

And ...

It was my understanding - perhaps wrong - that dict.copy() was an
add-on method to dict of non-ancient origin. How do I check?


http://www.python.org/doc/versions.html

pointers to all versions of docs since 1.4 which came out in 1996.

to see that method copy was already in 1.5 (1998):

http://www.python.org/doc/1.5/lib/no...00000000000000
00

I can't see it in 1.4 so I assume it was introduced between '96 and '98.

dict appeared in 2.2 (late 2001), see
http://www.python.org/doc/2.2/lib/built-in-funcs.html

consider this entire area a significant wart. I think I am entitled to
consider it so.


Given the apparent dearth of information in the matter, you may be
right. I'll do my best to keep clarifying my viewpoint in my books...


That would be excellant!


Anna (my wife and coeditor), hearing from me a summary of this
discussion, decided (and easily convinced me) that copying needs to be
the first recipe in the book, and we have already written and committed
it, so, unless we get a veto from David Ascher, the other coeditor, or
from O'Reilly, that might help. The recipe as it currently stands shows
copy.copy as the preferred way, with copy.deepcopy and calling the
object's type as secondary ways for particular needs, and L[:] as well
as [x for x in L] being specifically shown as wrong-headed approaches.
(We'll see how that survives tech review etc;-).
Alex
Jul 18 '05 #10

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

Similar topics

4
by: Scott Danzig | last post by:
I'm curious.. let's say you had: int val = 5; int a() { return val; } int &b() {
16
by: cppaddict | last post by:
Hi, I am deleting some objects created by new in my class destructor, and it is causing my application to error at runtime. The code below compiles ok, and also runs fine if I remove the body...
9
by: Tim Rentsch | last post by:
I have a question about what ANSI C allows/requires in a particular context related to 'volatile'. Consider the following: volatile int x; int x_remainder_arg( int y ){ return x % y; }
8
by: Bruce Vander Werf | last post by:
Because Rectangle is a value type, I know I can do this: Rectangle rect1, rect2; rect1.Top = 34; rect2 = rect1; //copies members rect1.Top = 46; //does not affect rect2 But what about an...
12
by: Jones | last post by:
I am having problems with my C# project. The project was built using VS.net (original release with service pack 1). The project includes windows forms and a DLL (dot.net) After getting the...
73
by: JoeC | last post by:
I am writing a game and I am having a challenge with my combat function. All I want to do is find out how to group pieces that are in the same space. There are two sides and all the units that...
20
by: tshad | last post by:
Using VS 2003, I am trying to take a class that I created to create new variable types to handle nulls and track changes to standard variable types. This is for use with database variables. This...
30
by: Logos | last post by:
I have what may be a bug, or may be a misunderstanding on how pass by reference and class inheritance works in PHP. Since I'm relatively new to PHP, I'm hoping for a little outside help to shed...
3
by: mk | last post by:
Hello everyone, I'm storing functions in a dictionary (this is basically for cooking up my own fancy schmancy callback scheme, mainly for learning purpose): .... return "f2 " + arg .......
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
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: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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...

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.