Modifying Class Object

T

T

Ok, just looking for a sanity check here, or maybe something I'm
missing. I have a class Test, for example:

class Test:
def __init__(self, param1, param2, param3):
self.param1 = param1
self.param2 = param2
self.param3 = param3

Next, I have a dictionary mytest that contains instances of Test. If
I want to modify one of the Test instances within my dictionary, I
have to rewrite the entire entry, correct (since Python passes by
value, not reference)? I.e. if I wish to change just param3 of an
instance, I would have to do:

def changevalue():
for key in mytest.keys():
currentparam = mytest[key]
param1 = currentparam.param1
param2 = currentparam.param2
param3 = currentparam.param3
param3 = "newvalue"
mytest[key] = Test(param1, param2, param3)

If there's an easier way to accomplish this that I'm missing, that'd
be great!
 
C

Chris Rebert

Ok, just looking for a sanity check here, or maybe something I'm
missing.  I have a class Test, for example:

class Test:
   def __init__(self, param1, param2, param3):
       self.param1 = param1
       self.param2 = param2
       self.param3 = param3

Next, I have a dictionary mytest that contains instances of Test.  If
I want to modify one of the Test instances within my dictionary, I
have to rewrite the entire entry, correct (since Python passes by
value, not reference)?

Incorrect; Python uses neither. See
http://effbot.org/zone/call-by-object.htm for a excellent explanation
of what Python does use.
I.e. if I wish to change just param3 of an
instance, I would have to do:

def changevalue():
   for key in mytest.keys():
       currentparam = mytest[key]
       param1 = currentparam.param1
       param2 = currentparam.param2
       param3 = currentparam.param3
       param3 = "newvalue"
       mytest[key] = Test(param1, param2, param3)

If there's an easier way to accomplish this that I'm missing, that'd
be great!

def changevalue():
for test in mytest.values():
test.param3 = "newvalue"

Cheers,
Chris
 
T

T

Ok, just looking for a sanity check here, or maybe something I'm
missing.  I have a class Test, for example:
class Test:
   def __init__(self, param1, param2, param3):
       self.param1 = param1
       self.param2 = param2
       self.param3 = param3
Next, I have a dictionary mytest that contains instances of Test.  If
I want to modify one of the Test instances within my dictionary, I
have to rewrite the entire entry, correct (since Python passes by
value, not reference)?

Incorrect; Python uses neither. Seehttp://effbot.org/zone/call-by-object.htmfor a excellent explanation
of what Python does use.
I.e. if I wish to change just param3 of an
instance, I would have to do:
def changevalue():
   for key in mytest.keys():
       currentparam = mytest[key]
       param1 = currentparam.param1
       param2 = currentparam.param2
       param3 = currentparam.param3
       param3 = "newvalue"
       mytest[key] = Test(param1, param2, param3)
If there's an easier way to accomplish this that I'm missing, that'd
be great!

def changevalue():
    for test in mytest.values():
        test.param3 = "newvalue"

Cheers,
Chris
--http://blog.rebertia.com

Thanks so much - this makes life a lot easier! And a great reference
as well.

Cheers,
Doug
 
S

Steve Holden

T said:
Ok, just looking for a sanity check here, or maybe something I'm
missing. I have a class Test, for example:

class Test:
def __init__(self, param1, param2, param3):
self.param1 = param1
self.param2 = param2
self.param3 = param3

Next, I have a dictionary mytest that contains instances of Test. If
I want to modify one of the Test instances within my dictionary, I
have to rewrite the entire entry, correct (since Python passes by
value, not reference)? I.e. if I wish to change just param3 of an
instance, I would have to do:

def changevalue():
for key in mytest.keys():
currentparam = mytest[key]
param1 = currentparam.param1
param2 = currentparam.param2
param3 = currentparam.param3
param3 = "newvalue"
mytest[key] = Test(param1, param2, param3)

If there's an easier way to accomplish this that I'm missing, that'd
be great!

def changevalue():
for key in mytest.keys():
mytest[key].param3 = "newvalue"

regards
Steve
 
A

Alf P. Steinbach

* Chris Rebert:
Incorrect; Python uses neither. See
http://effbot.org/zone/call-by-object.htm for a excellent explanation
of what Python does use.

Hm. While most everything I've seen at effbot.org has been clear and to the
point, that particular article reads like a ton of obfuscation.

Python passes pointers by value, just as e.g. Java does.

There, it needed just 10 words or so. :) Or perhaps some more words to point
out that in the Java language spec those reference values are called pointers,
but that this terminology isn't (apparently) used for Python, and isn't even
well known among Java programmers. But that's just one extra little para.

One just has to be clear about exactly what it is that's passed by value.

Not Python objects, but references (pointers) to them, the id(o) values.

I.e. if I wish to change just param3 of an
instance, I would have to do:

def changevalue():
for key in mytest.keys():
currentparam = mytest[key]
param1 = currentparam.param1
param2 = currentparam.param2
param3 = currentparam.param3
param3 = "newvalue"
mytest[key] = Test(param1, param2, param3)

If there's an easier way to accomplish this that I'm missing, that'd
be great!

def changevalue():
for test in mytest.values():
test.param3 = "newvalue"

Cheers,

- Alf
 
M

MRAB

Alf said:
* Chris Rebert:

Hm. While most everything I've seen at effbot.org has been clear and to
the point, that particular article reads like a ton of obfuscation.

Python passes pointers by value, just as e.g. Java does.

There, it needed just 10 words or so. :) Or perhaps some more words to
point out that in the Java language spec those reference values are
called pointers, but that this terminology isn't (apparently) used for
Python, and isn't even well known among Java programmers. But that's
just one extra little para.

One just has to be clear about exactly what it is that's passed by value.

Not Python objects, but references (pointers) to them, the id(o) values.
A reference is not the same as a pointer.

A pointer tells you where something is; a reference doesn't.
 
A

Alf P. Steinbach

* MRAB:
A reference is not the same as a pointer.

Depends on your choice terminology. I referred to the Java (language spec)
terminology to make it clear.

A pointer tells you where something is; a reference doesn't.

Sorry, I don't know of any relevant terminology where that is the case.


Cheers & hth.,

- Alf
 
S

Steve Holden

Alf said:
* MRAB:

Depends on your choice terminology. I referred to the Java (language
spec) terminology to make it clear.



Sorry, I don't know of any relevant terminology where that is the case.
Alf:

This topic was discussed at great, nay interminable, length about a year
ago. I'd appreciate it if you would search the archives and read what
was said then rather than hashing the whole topic over again to nobody's
real advantage.

regards
Steve
 
S

Steven D'Aprano

Alf:

This topic was discussed at great, nay interminable, length about a year
ago. I'd appreciate it if you would search the archives and read what
was said then rather than hashing the whole topic over again to nobody's
real advantage.

Curse you Steve, I had just come up with a brilliant rebuttal of Alf's
position. It was sheer genius, the sort of thing that would have James
Gosling weeping with envy.

Oh well, into the bitbucket it goes...
 
A

alex23

Alf P. Steinbach said:
Hm. While most everything I've seen at effbot.org has been clear and to the
point, that particular article reads like a ton of obfuscation.

Must. Resist. Ad hominem.
Python passes pointers by value, just as e.g. Java does.

There, it needed just 10 words or so. :)

10 words _plus_ an understanding of Java. Do you really think its
appropriate to discuss Python's behaviour purely in terms of other
languages?

Further, you've managed to define Python's behaviour as being somehow
_both_ of the major evaluation strategies - calling a reference by
value - so you're asking people to understand two totally irrelevant
models just to avoid describing one in its own terms. Rather than
arguing about whether you have a 'value' or a 'reference', it's a lot
easier to explain that you're passing mutable & immutable objects
around. The behaviour is thus defined in terms of the object and _not_
in the calling model, and is far more consistent with object
references throughout the language. It also doesn't require reference
to other languages simply to define Python's model in terms of what it
isn't.
 
A

Alf P. Steinbach

* Steve Holden:
Alf:

This topic was discussed at great, nay interminable, length about a year
ago. I'd appreciate it if you would search the archives and read what
was said then rather than hashing the whole topic over again to nobody's
real advantage.

Well that's my point, and thanks for backing me up on that :): it's very
simple, and as demonstrated can be expressed in 10 words or less (plus perhaps a
terminology reference, as I did above), so all that discussion and in particular
the lengthy article at effbot serves as obfuscation and nothing else.

By the way, most every programming language has some corner like that, something
that is utterly simple but somehow has some kind of obfuscation-meme attached.

In C++ it's "call" and "constructor". It doesn't help that the language's
standard lays down the law on it, it doesn't help that the language's creator
has laid down the law, it doesn't help that it's utterly and completely simple.
Somehow newbies and even some experienced people manage to create their own
terminological nightmare and drawing conclusions about reality from that
misguided obfuscated view, and then discussing it up and down and sideways.


Cheers & hth.,

- Alf
 
S

Steven D'Aprano

Python passes pointers by value, just as e.g. Java does.

How do I get a pointer in pure Python code (no ctypes)? I tried both
Pascal and C syntax (^x and *x), but both give syntax errors.

For that matter, how do I get a pointer in Java code?

If Python doesn't have pointers, then why are you talking about Python
passing pointers? It's a vacuous truth, like saying that Python passes
dinosaurs by name.
 
T

T

Oops, this one was my fault - the object I was having the issues with
was actually a shelve file, not a dictionary..so just re-assigning the
variable isn't working, but re-writing the object to the shelve file
does. So in this case, is there any way to just change a single
value, or am I stuck rewriting the entry?
 
S

Steven D'Aprano

Sorry, I don't know of any relevant terminology where that is the case.

Taken from Wikipedia:

"A pointer is a simple, less abstracted implementation of the more
abstracted reference data type (although it is not as directly usable as
a C++ reference)."

http://en.wikipedia.org/wiki/Pointer_(computing)

In other words, a pointer is a specific type of reference. A reference in
turn is an opaque but low-level data type which "refers to" in some way
to the data you actually care about. (C++ has a concrete reference type,
which is not to be confused with abstract references.)

http://en.wikipedia.org/wiki/Reference_(computer_science)

Unless otherwise stated, references are opaque and coders need not care
how the reference mechanism is implemented, see e.g.:

http://www.cocoabuilder.com/archive/cocoa/20777-opaque-reference.html

In Python you don't use references directly, there is no reference type
or object. You can simulate the semantics of references (but not
pointers) by putting your object in a list and passing the list around.
 
A

Alf P. Steinbach

* Steven D'Aprano:
How do I get a pointer in pure Python code (no ctypes)? I tried both
Pascal and C syntax (^x and *x), but both give syntax errors.

Well, I don't believe that you tried that. :)

From one point of view it's extremely easy: just create some object, even just
type 42 as an integer literal, and you can apply all of Python's pointer
operations to the result -- which isn't much, basically just checking for
pointer equality via 'is' or applying 'id' to get a value that represents the
pointer uniquely, or copying the pointer via assignment or parameter passing.

Whether you can obtain the bits of the internal pointer value, represented as
e.g. an int, formally depends on the Python implementation.

In CPython the 'id' function provides the internal pointer value as an int.

I.e., with CPython you can do

def foo( o ):
print( id( o ) ) # Shows the pointer value in decimal.

whatever = 42
print( id( whatever ) ) # Shows the pointer value in decimal.
foo( whatever ) # Shows the exact *same* pointer value.

which at a slightly higher level of abstraction works just as well with any
conceivable Python implementation, although you have no formal guarantee that
the conceptual "pointer" values are actually the internally memory addresses.

But, in CPython they are, and you run into them all the time, for example (where
the "at" tells you that it's a memory location specification, a pointer),
For that matter, how do I get a pointer in Java code?

As with Python, from one point of view it's extremely easy, just 'new' some
object, and then you can apply all of Java's pure pointer operations to the
result -- which isn't much, basically just checking for pointer equality and
copying a pointer via assignment or parameter passing.

In Java it's a pointer by definition, namely the language spec's definition.

From another point of view, getting at the internal representation of the
pointer is a bit harder in Java than in Python, at least as far as I know. It
may not be practically possible. Disclaimer: I'm not a Java expert, and haven't
used Java for years, and it just might be possible by using JNI (Java Native
Interface), but that requires you to write a dynamic library in e.g. C or C++,
and as I recall Java just creates a kind of fixed reference for the duration of
a JNI call so the JNI side of things may not tell you anything about the Java
side of things before or after the call.

But if it helps, just to learn about pointers in various languages you -- or
rather, some other reader, because I suspect that you know this already! :) --
might look at <url: http://cslibrary.stanford.edu/106/>.

It contains a simple pointers example expressed in four different languages,
namely C, C++, Pascal and Java, in particular comparing C and Java.

If Python doesn't have pointers, then why are you talking about Python
passing pointers? It's a vacuous truth, like saying that Python passes
dinosaurs by name.

See above.


Cheers & hth.,

- Alf
 
A

Alf P. Steinbach

* Steven D'Aprano:
Taken from Wikipedia:

"A pointer is a simple, less abstracted implementation of the more
abstracted reference data type (although it is not as directly usable as
a C++ reference)."

http://en.wikipedia.org/wiki/Pointer_(computing)

In other words, a pointer is a specific type of reference. A reference in
turn is an opaque but low-level data type which "refers to" in some way
to the data you actually care about. (C++ has a concrete reference type,
which is not to be confused with abstract references.)

http://en.wikipedia.org/wiki/Reference_(computer_science)

Unless otherwise stated, references are opaque and coders need not care
how the reference mechanism is implemented, see e.g.:

http://www.cocoabuilder.com/archive/cocoa/20777-opaque-reference.html

In Python you don't use references directly, there is no reference type
or object. You can simulate the semantics of references (but not
pointers) by putting your object in a list and passing the list around.

Yes, sort of.

The last paragraph however confuses two different meanings of "reference".

So when using terms such as "reference" it helps to refer :) to some specific
terminology, unless that's clearly understood from context.


Cheers,

- Alf
 
A

Arnaud Delobelle

Alf P. Steinbach said:
* Chris Rebert:

Hm. While most everything I've seen at effbot.org has been clear and
to the point, that particular article reads like a ton of obfuscation.

Python passes pointers by value, just as e.g. Java does.


Please! Not this again! This has been discussed to death and beyond more
than enough times. Go search the c.l.p archives, read it all, and I'm
sure you won't want to add anything anymore.
 
G

Gerard Flanagan

Arnaud said:
Please! Not this again! This has been discussed to death and beyond more
than enough times. Go search the c.l.p archives, read it all, and I'm
sure you won't want to add anything anymore.

+1 !!
 
S

Steve Holden

Steven said:
Curse you Steve, I had just come up with a brilliant rebuttal of Alf's
position. It was sheer genius, the sort of thing that would have James
Gosling weeping with envy.

Oh well, into the bitbucket it goes...
You're a better man for it, Steven! Admirable self-restraint ...

regards
Steve
 
S

Steve Holden

Alf said:
* Steve Holden: [...]
Alf:

This topic was discussed at great, nay interminable, length about a year
ago. I'd appreciate it if you would search the archives and read what
was said then rather than hashing the whole topic over again to nobody's
real advantage.

Well that's my point, and thanks for backing me up on that :): it's
very simple, and as demonstrated can be expressed in 10 words or less
(plus perhaps a terminology reference, as I did above), so all that
discussion and in particular the lengthy article at effbot serves as
obfuscation and nothing else.
Please don't assume I was trying to support you. Your remarks showed
considerable ignorance of issue that were extremely nuanced. Whatever
point you were trying to make was lost in your self-aggrandizing
disrespect of Fredrik Lundh, a software engineer of some repute with a
long history of contribution to Python. The fact that your post was
basically a restatement of one of the several competing positions in
that thread makes it no more right than any of the others.
By the way, most every programming language has some corner like that,
something that is utterly simple but somehow has some kind of
obfuscation-meme attached.
Why thank you for the education. Somehow in my 40-odd years of
programming I had quite overlooked that fact. Which helps how?
In C++ it's "call" and "constructor". It doesn't help that the
language's standard lays down the law on it, it doesn't help that the
language's creator has laid down the law, it doesn't help that it's
utterly and completely simple. Somehow newbies and even some experienced
people manage to create their own terminological nightmare and drawing
conclusions about reality from that misguided obfuscated view, and then
discussing it up and down and sideways.
Which IMHO you have done little to assist. Just how exactly *do* we
succeed in asking you not to discuss something?

yours intemperate-ly - steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top