469,602 Members | 1,638 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,602 developers. It's quick & easy.

Confused yet again: Very Newbie Question

mcl
Why can I not the change the value of a variable in another class,
when I have passed it via a parameter list.

I am sure I am being stupid, but I thought passed objects were Read/
Write

eg
------------------------------------------------------------
#!/usr/bin/python

class one(): #my Global Vars
fred = 'fred'

class three():
def createJoe(self, myName):
c1 = one()
myName = 'Joe' #********************* Question why does this
not change variable fred in 'class one'
print 'Three(Local): ' + myName + ' Three(Global): ' +
c1.fred

def main():
c1 = one()
c3 =three()
c3.createJoe(c1.fred)
if __name__ == '__main__' : main()

Results:
Three(Local): Joe Three(Global): fred

'fred' in 'class one' does not get changed to 'joe' in 'class three'
'createJoe', even though I have passed 'class one' 'fred' to
'createJoe'

I hope this makes sense.

I did not think you had to make the distinction between 'byvar' and
'byref' as in Basic.

Thanks

Richard
Jul 7 '08 #1
10 920
mcl wrote:
Why can I not the change the value of a variable in another class,
when I have passed it via a parameter list.

I am sure I am being stupid, but I thought passed objects were Read/
Write
In Python, there are names which are bound to objects. Doing "foo = bar"
and then "foo = spam" (re)binds the name "foo" to the same object as
"spam" is bound to. This doesn't have any effect on any other names that
were bound to the same object as "bar".
eg
------------------------------------------------------------
#!/usr/bin/python

class one(): #my Global Vars
fred = 'fred'

class three():
def createJoe(self, myName):
Here, the local name "myName" is bound to the same string object as
one.fred.
c1 = one()
myName = 'Joe' #********************* Question why does this
not change variable fred in 'class one'
Here, you rebind the local name "myName" to the string object 'Joe'.
This doesn't change what one.fred is bound to.
print 'Three(Local): ' + myName + ' Three(Global): ' +
c1.fred

def main():
c1 = one()
c3 =three()
c3.createJoe(c1.fred)
if __name__ == '__main__' : main()

Results:
Three(Local): Joe Three(Global): fred

'fred' in 'class one' does not get changed to 'joe' in 'class three'
'createJoe', even though I have passed 'class one' 'fred' to
'createJoe'

I hope this makes sense.

I did not think you had to make the distinction between 'byvar' and
'byref' as in Basic.

Thanks

Richard
There are a couple good articles about this online. The one below is
lengthy and has ASCII art, but I don't remember if I liked it.

<http://starship.python.net/crew/mwh/hacks/objectthink.html>

BTW, in this example, there doesn't seem to be any need for you to be
using classes. Also, you should always use new-style classes unless you
have a specific reason not to
>>class MyClass(object):
--
Jul 7 '08 #2
When you call c3.createJoe(c1.fred), you are passing a copy of the
value stored in c1.fred to your function. Python passes function
parameters by value. The function will not destructively modify its
arguments; you must expliticly state your intention to modify an
object:

class one():
fred = 'fred'

class three():
def createJoe(self, myName):
return "Joe"

def main():
c1 = one()
c3 = three()
c1.fred = c3.createJoe() # Modify c1's attribute, fred, with the
return value from c3.createJoe
Jul 7 '08 #3
mcl
On 7 Jul, 13:09, Jeff <jeffo...@gmail.comwrote:
When you call c3.createJoe(c1.fred), you are passing a copy of the
value stored in c1.fred to your function. *Python passes function
parameters by value. *The function will not destructively modify its
arguments; you must expliticly state your intention to modify an
object:

class one():
* * fred = 'fred'

class three():
* * def createJoe(self, myName):
* * * * return "Joe"

def main():
* * c1 = one()
* * c3 = three()
* * c1.fred = c3.createJoe() # Modify c1's attribute, fred, with the
return value from c3.createJoe
Thank you very much for your helpful replies.

Two questions:
One:
My use of classes is because I want two classes one for global
variables and one for global functions.
A function may set multiple global variable values, so what is the
best way to do this as 'return' only appears to be able to set one
value.
Two:
I am sorry but I do not understand the significance defining a Class
as:
>>class MyClass(object):
what is object ?

I am using python with Google App Engine, and I only have Alex
Martelli's book up to Python 2.2, if they has any relevance ?

Thanks again for your help. I now understand what my mistakes were and
why I was not getting the results I had expected.

Richard
Jul 7 '08 #4
mcl wrote:
On 7 Jul, 13:09, Jeff <jeffo...@gmail.comwrote:
>When you call c3.createJoe(c1.fred), you are passing a copy of the
value stored in c1.fred to your function. Python passes function
parameters by value. The function will not destructively modify its
arguments; you must expliticly state your intention to modify an
object:

class one():
fred = 'fred'

class three():
def createJoe(self, myName):
return "Joe"

def main():
c1 = one()
c3 = three()
c1.fred = c3.createJoe() # Modify c1's attribute, fred, with the
return value from c3.createJoe

Thank you very much for your helpful replies.

Two questions:
One:
My use of classes is because I want two classes one for global
variables and one for global functions.
That's odd. Usually, you shouldn't be using any globals at all. Callers
should use their own local variables, or instances or whatever.
A function may set multiple global variable values, so what is the
best way to do this as 'return' only appears to be able to set one
value.
You can return a tuple, and then use tuple unpacking.
>>def f():
.... return 1, 2
>>one, two = f()
one
1
>>two
2
Two:
I am sorry but I do not understand the significance defining a Class
as:
>>class MyClass(object):
what is object ?

I am using python with Google App Engine, and I only have Alex
Martelli's book up to Python 2.2, if they has any relevance ?
By inheriting from object, your class becomes a new-style class.
Otherwise, it's old-style. Honestly, I don't know all of the
differences, but new-style classes are better. For one thing, old-style
classes don't support properties or super().

They were introduced in Python 2.2. Your Python 2.2 book probably
centers around old-style classes.
Thanks again for your help. I now understand what my mistakes were and
why I was not getting the results I had expected.

Richard
--
Jul 7 '08 #5
On Mon, Jul 7, 2008 at 7:30 AM, mcl <mc********@googlemail.comwrote:
I did not think you had to make the distinction between 'byvar' and
'byref' as in Basic.
Python does not use "call by value" or "call by reference" semantics.
Instead, python's model is "call by object". See this writeup for
some details: http://effbot.org/zone/call-by-object.htm

--
Jerry
Jul 7 '08 #6
On Mon, 7 Jul 2008 05:41:22 -0700 (PDT), mcl <mc********@googlemail.comwrote:
[snip]
My use of classes is because I want two classes one for global
variables and one for global functions.
One of the many lovely things about programming in the
Python style is that very few things need to be global.
When you make something global, you're in effect saying
that it has no particular connection to anything else.
If it has a connection to something else, then it should
probably be combined into an object with that something
else.

--
To email me, substitute nowhere->spamcop, invalid->net.
Jul 7 '08 #7
Jerry Hill wrote:
On Mon, Jul 7, 2008 at 7:30 AM, mcl <mc********@googlemail.comwrote:
>I did not think you had to make the distinction between 'byvar' and
'byref' as in Basic.

Python does not use "call by value" or "call by reference" semantics.
Instead, python's model is "call by object". See this writeup for
some details: http://effbot.org/zone/call-by-object.htm
Ah-ha! That's the article I've been trying to find! I can never remember
"effbot"'s name. Thanks!
--
Jul 7 '08 #8
mcl
On Jul 7, 5:07*pm, Dennis Lee Bieber <wlfr...@ix.netcom.comwrote:
On Mon, 7 Jul 2008 05:41:22 -0700 (PDT), mcl <mcl.off...@googlemail.com>
declaimed the following in comp.lang.python:
My use of classes is because I want two classes one for *global
variables and one for global functions.

* * * * Which seems to violate the entire reason for using "classes" (and
sounds like something that Java's syntax forces upon one). Classes (and
instances of them) are typically defined to /combine/ the class/instance
specific data and the functions that operate upon that data into a
single object.

* * * * If you just need a container for so-called "global" data,create a
module. Same for utility functions.

-=-=-=-=-=- * * * * * * myGlobalData.py

something = 1
else = 3

-=-=-=-=-=- * * * * * * myUtilityFuncs.py

def weird(a, b):
* * * * return (a-b, b-a, a*b, a/b, float(a)/b)

-=-=-=-=-=- * * * * * * main.py

import myGlobalData
import myUtilityFuncs

results = myUtilityFuncs.weird(myGlobalData.something,
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * myGlobalData.else)
print results
myGlobalData.something = results[2]
A function may set multiple global variable values, so what is the
best way to do this as 'return' only appears to be able to set one
value.

--
* * * * Wulfraed * * * *Dennis Lee Bieber * * * ** * * KD6MOG
* * * * wlfr...@ix.netcom.com * * * * * * wulfr...@bestiaria.com
* * * * * * * * HTTP://wlfraed.home.netcom.com/
* * * * (Bestiaria Support Staff: * * * * * * * web-a...@bestiaria.com)
* * * * * * * * HTTP://www.bestiaria.com/
Dennis,

Thank you for this reply. You are correct in what I was trying to do
and thank you for your very good example. I will now rewrite my code
changing classes to modules, which make more sense to me, even if it
is not proper Python.

I am much wiser about classes, but still a long way from fully
comprehending when and where to best use them.

Thank you all for your replies and links, as it solved my problems
enough, to get some code working.

Richard
Jul 7 '08 #9


Jeff wrote:
When you call c3.createJoe(c1.fred), you are passing a copy of the
value stored in c1.fred to your function. Python passes function
parameters by value.
These statements are both wrong. Function argument objects or objects
derived therefrom are bound to function parameter names. One could say
that Python calls by cross-namespace assignment. No copying is done,
anymore than with assignment statements.

It returns objects the same way if there is a target to receive them.
The function will not destructively modify its arguments;
If the argument is mutable and the function calls a mutation method of
the object, it is mutated.

tjr

Jul 7 '08 #10
Lie
On Jul 7, 7:09*pm, Jeff <jeffo...@gmail.comwrote:
When you call c3.createJoe(c1.fred), you are passing a copy of the
value stored in c1.fred to your function. *Python passes function
parameters by value.
No, python doesn't pass variable either by value or by reference. The
behavior in python is a bit of mix between passing by value and by
reference, because python use different variable model than Basic (in
short, saying passing by reference or value in python doesn't make
sense). In python, variables are names referring to an object, in
Basic variables are the object itself. In python, when you pass
variable as function parameter, you pass the object to the function
and inside the function a new name is rebound to that object. These
two names are not related in any way except that they refers to the
same object.

In python an immutable object can't be changed after creation and
string is immutable, so when you reassign 'Joe' to myName, a string
object 'Joe' is created and assigned to myName, myName's original
string object ('fred') isn't affected and other names that refers to
the string object 'fred' (i.e. c1.fred, one.fred) isn't changed. If
you want to change all those values too, you'd have to change the
inner string object itself (which is impossible since string object is
immutable). If the object referred is mutable (e.g. list, dictionary)
that example would work.
>*The function will not destructively modify its
arguments; you must expliticly state your intention to modify an
object:

class one():
* * fred = 'fred'

class three():
* * def createJoe(self, myName):
* * * * return "Joe"

def main():
* * c1 = one()
* * c3 = three()
* * c1.fred = c3.createJoe() # Modify c1's attribute, fred, with the
return value from c3.createJoe
Jul 8 '08 #11

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.