Return value of an assignment statement?

M

mrstephengross

Hi all. In C, an assignment statement returns the value assigned. For
instance:

int x
int y = (x = 3)

In the above example, (x=3) returns 3, which is assigned to y.

In python, as far as I can tell, assignment statements don't return
anything:

y = (x = 3)

The above example generates a SyntaxError.

Is this correct? I just want to make sure I've understood the
semantics.

Thanks,
--Steve
 
J

John Henry

Hi all. In C, an assignment statement returns the value assigned. For
instance:

int x
int y = (x = 3)

In the above example, (x=3) returns 3, which is assigned to y.

In python, as far as I can tell, assignment statements don't return
anything:

y = (x = 3)

The above example generates a SyntaxError.

Is this correct? I just want to make sure I've understood the
semantics.

Thanks,
--Steve

That's true, and I am happy that they decided to make that a syntax
error.
 
J

Jeff Schwab

mrstephengross said:
Hi all. In C, an assignment statement returns the value assigned. For
instance:

int x
int y = (x = 3)

In the above example, (x=3) returns 3, which is assigned to y.

In python, as far as I can tell, assignment statements don't return
anything:

y = (x = 3)

The above example generates a SyntaxError.

Is this correct? I just want to make sure I've understood the
semantics.

Yes, but there is valid syntax for the common case you mentioned:

y = x = 3

What you can't do (that I really miss) is have a tree of assign-and-test
expressions:

import re
pat = re.compile('some pattern')

if m = pat.match(some_string):
do_something(m)
else if m = pat.match(other_string):
do_other_thing(m)
else:
do_default_thing()
 
7

7stud

Hi all. In C, an assignment statement returns the value assigned. For
instance:

  int x
  int y = (x = 3)

In the above example, (x=3) returns 3, which is assigned to y.

In python, as far as I can tell, assignment statements don't return
anything:

  y = (x = 3)

The above example generates a SyntaxError.

Is this correct? I just want to make sure I've understood the
semantics.

Thanks,
--Steve

x = y = 1
print x, y

--output:--
1 1

With parentheses, it looks like python thinks you are trying to do a
boolean == inside the parentheses. It's the same error you get if you
write:

if x = y:
print 'yes'
 
J

John Henry

That's true, and I am happy that they decided to make that a syntax
error.

BTW: The less obvious issues when coming from the C world are Python
syntax like these:

y = x = 3

a = 4

y = x = a

print x,y

a = 5

print x,y
 
M

mrstephengross

What you can't do (that I really miss) is have a tree of assign-and-test
expressions:
import re
pat = re.compile('some pattern')
if m = pat.match(some_string):
do_something(m)

Yep, this is exactly what I am (was) trying to do. Oh well.... Any
clever ideas on this front?

--Steve
 
J

Jeff Schwab

John said:
BTW: The less obvious issues when coming from the C world are Python
syntax like these:

y = x = 3

a = 4

y = x = a

print x,y

a = 5

print x,y

That's the same behavior I would expect in C, on the grounds that C
assignments do bit-wise copies. What I found confusing at first was
that the same variable will either directly store or merely refer to an
object, depending on the type of the object:
>>> a = [ 'hello' ]
>>> y = x = a
>>> a += [ 'world' ]
>>> print x, y
['hello', 'world'] ['hello', 'world']
 
J

Jeff Schwab

mrstephengross said:
Yep, this is exactly what I am (was) trying to do. Oh well.... Any
clever ideas on this front?

I worked around it by defining a separate thigamabob with a "result"
property. A method of the thigamabob internally performs the
assignment, and returns a boolean result. The body of each branch in
the tree can then retrieve the result object from the thigamabob.
Here's an example hard-coded to match strings against patterns, but I
think the idea should be extensible to other kinds of assign-and-test
situations.

# Just for the sake of this post.
def do_something(m): pass
def do_other_thing(m): pass
def do_default_thing(): pass

import re

class Matcher(object):
def __call__(self, pattern, string):
self.result = pattern.match(string)

if __name__ == '__main__':

pat = re.compile('some pattern')
match = Matcher()

if match(pat, 'a'):
do_something(match.result)
elif match(pat, 'b'):
do_other_thing(match.result)
else:
do_default_thing()
 
J

John Henry

BTW: The less obvious issues when coming from the C world are Python
syntax like these:
y = x = 3
y = x = a
print x,y
print x,y

That's the same behavior I would expect in C, on the grounds that C
assignments do bit-wise copies. What I found confusing at first was
that the same variable will either directly store or merely refer to an
object, depending on the type of the object:
a = [ 'hello' ]
y = x = a
a += [ 'world' ]
print x, y
['hello', 'world'] ['hello', 'world']

Yep. Took me a while to realize there is mutable objects, and non-
mutable objects. To be honest, I am still not too comfortable about
it. For instance, I still get nervous for code like:

def invoke_some_fct(parent):
y = parent.x
y += [ 'world' ]
print y, parent.x

class abc:
def __init__(self):
self.x=[ 'hello' ]
invoke_some_fct(self)
print self.x

hw = abc()
 
M

Martin v. Löwis

Hi all. In C, an assignment statement returns the value assigned.

No. C doesn't have an assignment statement. Instead, in C, assignment
is an expression (just like a binary operation or a function call);
that expression evaluates to the value assigned (i.e. the result is
the value, the assignment is just a side-effect).

What you consider the assignment statement is actually an expression
statement, of the syntax

<expression> <semicolon>

So

x = y;
f();
3+4;

are all the same kind of statement.
In python, as far as I can tell, assignment statements don't return
anything:

Right - that's because they are statements. No statement "returns"
a value - except for the return statement, of course, but it doesn't
return it in the sense that you could write

foo = return 44

Because of the confusing meaning of "return", I find it better to
say that expressions evaluate to a value, not that they return
a value.
The above example generates a SyntaxError.

Is this correct? I just want to make sure I've understood the
semantics.

Please try to study more on the difference between expressions
and statements.

Regards,
Martin

P.S. Just to confuse matters: GNU C also has statement expressions,
of the form

({ int y = foo (); int z;
if (y > 0) z = y;
else z = - y;
z; })

These are expressions, but allow the expressiveness of statements
(including variable declarations)
 
T

Terry Reedy

| That's the same behavior I would expect in C, on the grounds that C
| What I found confusing at first was
| that the same variable will either directly store or merely refer to an
| object, depending on the type of the object:

Since names and collection slots always refer to objects, I find the above
confusing. Can you clarify what difference you percieve?

tjr
 
B

bruno.desthuilliers

BTW: The less obvious issues when coming from the C world are Python
syntax like these:
y = x = 3
y = x = a
print x,y
print x,y

That's the same behavior I would expect in C, on the grounds that C
assignments do bit-wise copies. What I found confusing at first was
that the same variable will either directly store or merely refer to an
object, depending on the type of the object:
a = [ 'hello' ]
y = x = a
a += [ 'world' ]
print x, y
['hello', 'world'] ['hello', 'world']

There's nothing like a variable "storing" anything in Python. All you
have are names to (references to) objects binding in a namespace. Now
the fact is that some types are mutable and other are not. In your
above example, the augmented assignment does *not* rebind a, but
invoke a.extend(). With integers, it would have rebind a. So while
your observation is exact, your interpretation is wrong !-)
 
B

bruno.desthuilliers

That's the same behavior I would expect in C, on the grounds that C
assignments do bit-wise copies. What I found confusing at first was
that the same variable will either directly store or merely refer to an
object, depending on the type of the object:
a = [ 'hello' ]
y = x = a
a += [ 'world' ]
print x, y
['hello', 'world'] ['hello', 'world']

Yep. Took me a while to realize there is mutable objects, and non-
mutable objects. To be honest, I am still not too comfortable about
it. For instance, I still get nervous for code like:

def invoke_some_fct(parent):
y = parent.x
y += [ 'world' ]
print y, parent.x

class abc:
def __init__(self):
self.x=[ 'hello' ]
invoke_some_fct(self)
print self.x

Explicitely using list.extend would make things clearer:

def invoke_some_fct(parent):
parent.x.extend(['world'])

Now there's no reason to feel nervous about this. All you have to
remember is that Python never copy anything unless explicitely asked
for.
 
B

bruno.desthuilliers

What you can't do (that I really miss) is have a tree of assign-and-test
expressions:

import re
pat = re.compile('some pattern')

if m = pat.match(some_string):
do_something(m)
else if m = pat.match(other_string):
do_other_thing(m)
else:
do_default_thing()

What you want is:

for astring, afunc in ((some_string, do_something), (other_string,
do_other_thing)):
m = pat.match(astring)
if m:
afunc(m)
break
else:
do_default_thing()
 
S

Steve Holden

mrstephengross said:
Yep, this is exactly what I am (was) trying to do. Oh well.... Any
clever ideas on this front?
The syntax is the way it is precisely to discourage that kind of clever
idea. Of course, people nevertheless manage to work around the
restriction to try and make their Python read like some other language
they are more familiar with, and most of the time they get away with it.

The fat remains that in programming there *is* such a thing as being too
clever, and Python's syntax deliberately discourages that.

regards
Steve
 
J

Jeff Schwab

John Henry wrote:
Hi all. In C, an assignment statement returns the value assigned. For
instance:
int x
int y = (x = 3)
In the above example, (x=3) returns 3, which is assigned to y.
In python, as far as I can tell, assignment statements don't return
anything:
y = (x = 3)
The above example generates a SyntaxError.
Is this correct? I just want to make sure I've understood the
semantics.
Thanks,
--Steve
That's true, and I am happy that they decided to make that a syntax
error.
BTW: The less obvious issues when coming from the C world are Python
syntax like these:
y = x = 3
a = 4
y = x = a
print x,y
a = 5
print x,y
That's the same behavior I would expect in C, on the grounds that C
assignments do bit-wise copies. What I found confusing at first was
that the same variable will either directly store or merely refer to an
object, depending on the type of the object:
a = [ 'hello' ]
y = x = a
a += [ 'world' ]
print x, y
['hello', 'world'] ['hello', 'world']
Yep. Took me a while to realize there is mutable objects, and non-
mutable objects. To be honest, I am still not too comfortable about
it. For instance, I still get nervous for code like:

def invoke_some_fct(parent):
y = parent.x
y += [ 'world' ]
print y, parent.x

class abc:
def __init__(self):
self.x=[ 'hello' ]
invoke_some_fct(self)
print self.x

Explicitely using list.extend would make things clearer:

def invoke_some_fct(parent):
parent.x.extend(['world'])

Whether you use += or extend has nothing to do with it. You omitted the
relevant part. Using extend, it would look like:

y = parent.x
y.extend(['world'])

The confusing part is that performing an operation on y may or may not
alter parent.x, depending on whether the initial type of parent.x is
immutable. If parent.x is immutable, y is a copy of the value
represented by parent.x, and modifying y has not effect on the value of
parent.x. If (OTOH) parent.x is mutable, then x and y are really
references to the same object, and modifications to that object via y
can be observed via x. In C, you use pointers to get this effect.

Now there's no reason to feel nervous about this. All you have to
remember is that Python never copy anything unless explicitely asked
for.

It's not that simple. After a statement like:

a = b

Whether a and b denote the same object depends on what kind of object b
represented in the first place.
 
S

Steve Holden

Jeff said:
(e-mail address removed) wrote: [...]
Now there's no reason to feel nervous about this. All you have to
remember is that Python never copy anything unless explicitely asked
for.

It's not that simple. After a statement like:

a = b

Whether a and b denote the same object depends on what kind of object b
represented in the first place.

Surely this is exactly wrong. Is there a single example you can think of
where

a = b
assert a is b, "Oops!"

would raise and exception? Perhaps you meant to use an augmented
assignment operation?

regards
Steve
 
J

Jeff Schwab

Terry said:
| That's the same behavior I would expect in C, on the grounds that C
| What I found confusing at first was
| that the same variable will either directly store or merely refer to an
| object, depending on the type of the object:

Since names and collection slots always refer to objects, I find the above
confusing. Can you clarify what difference you percieve?

a += b

Whether a refers to the same object before and after that statement
depends on what type of object it referred to before the statement.
 
J

Jeff Schwab

John said:
Hi all. In C, an assignment statement returns the value assigned. For
instance:
int x
int y = (x = 3)
In the above example, (x=3) returns 3, which is assigned to y.
In python, as far as I can tell, assignment statements don't return
anything:
y = (x = 3)
The above example generates a SyntaxError.
Is this correct? I just want to make sure I've understood the
semantics.
Thanks,
--Steve
That's true, and I am happy that they decided to make that a syntax
error.
BTW: The less obvious issues when coming from the C world are Python
syntax like these:
y = x = 3
a = 4
y = x = a
print x,y
a = 5
print x,y
That's the same behavior I would expect in C, on the grounds that C
assignments do bit-wise copies. What I found confusing at first was
that the same variable will either directly store or merely refer to an
object, depending on the type of the object:
a = [ 'hello' ]
y = x = a
a += [ 'world' ]
print x, y
['hello', 'world'] ['hello', 'world']

There's nothing like a variable "storing" anything in Python. All you
have are names to (references to) objects binding in a namespace. Now
the fact is that some types are mutable and other are not. In your
above example, the augmented assignment does *not* rebind a, but
invoke a.extend(). With integers, it would have rebind a. So while
your observation is exact, your interpretation is wrong !-)

Thank you for the clarification. For some reason, I had it in my head
that ints were packed directly into the C structures that represent
Python variables, in the same (union?) member that otherwise would store
a pointer.
 
J

Jeff Schwab

Steve said:
Jeff said:
(e-mail address removed) wrote: [...]
Now there's no reason to feel nervous about this. All you have to
remember is that Python never copy anything unless explicitely asked
for.

It's not that simple. After a statement like:

a = b

Whether a and b denote the same object depends on what kind of object
b represented in the first place.

Surely this is exactly wrong. Is there a single example you can think of
where

a = b

a += b (my bad)
assert a is b, "Oops!"

would raise and exception? Perhaps you meant to use an augmented
assignment operation?

Why, yes I did! Sorry about that.
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top