Warning of missing side effects

T

Tobias Weber

Hi,
being new to Python I find remarkable that I don't see any side effects.
That's especially true for binding. First, it is a statement, so this
won't work:

if x = q.pop():
print x # output only true values

Second, methods in the standard library either return a value OR modify
the reciever, so even if assignment was an expression the above wouldn't
work.

Only it still wouldn't, because IF is a statement as well. So no ternary:

x = if True: 5 else: 7;

However there is one bit of magic, functions implicitly return None. So
while the following will both run without error, only one actually works:

x = 'foo'.upper()
y = ['f', 'b'].reverse()

Now I mentioned that the mutable types don't have functions that mutate
and return something, so I only have to remember that...

But I'm used to exploiting side effect, and sometimes forget this rule
in my own classes. IS THERE A WAY to have the following produce a
runtime error?

def f():
x = 5
# no return

y = f()

Maybe use strict ;)
 
P

Pascal Chambon

Tobias Weber a écrit :
Hi,
being new to Python I find remarkable that I don't see any side effects.
That's especially true for binding. First, it is a statement, so this
won't work:

if x = q.pop():
print x # output only true values

Second, methods in the standard library either return a value OR modify
the reciever, so even if assignment was an expression the above wouldn't
work.

Only it still wouldn't, because IF is a statement as well. So no ternary:

x = if True: 5 else: 7;

However there is one bit of magic, functions implicitly return None. So
while the following will both run without error, only one actually works:

x = 'foo'.upper()
y = ['f', 'b'].reverse()

Now I mentioned that the mutable types don't have functions that mutate
and return something, so I only have to remember that...

But I'm used to exploiting side effect, and sometimes forget this rule
in my own classes. IS THERE A WAY to have the following produce a
runtime error?

def f():
x = 5
# no return

y = f()

Maybe use strict ;)
Hello

Just to note that if "['f', 'b'].reverse()" doesn't return the new
value, there is a corersponding function : "reversed(mylist)" which does
it (idem, sorted(list) <-> list.sort()) B-)

Concerning your question on warnings, well I guess that after a little
time in python, you won't make mistakes on "side effects" anymore ;

But if you want to add checks to your methods, you should see towards
decorators or metaclasses : they allow you to wrap your methods inside
other methods, of which the only point couldbe, for example, to check
what your methods returtn and raise a warning if it returns "None". But
the problem is, sometimes you WANT them to return None....

If you want to detect methods that don't have explicit "return"
statements, then you'll have to play with abstract syntax trees it
seems... much trouble for not much gain.
I guess you'll quickly get the pythonic habits without needing all that ^^

Regards,
pascal
 
M

Martin v. Löwis

But I'm used to exploiting side effect, and sometimes forget this rule
in my own classes. IS THERE A WAY to have the following produce a
runtime error?

def f():
x = 5
# no return

y = f()

Typically, this will produce a runtime error fairly quickly,
namely when you *use* the (presumed) return value of f().
You would normally try to perform some computation with y,
or invoke methods on it - and then you see that it is None.

So while it is not possible to get an exception on the
assignment, you will usually get a runtime error sooner
or later (most of the time, sooner).

FWIW, pylint -e reports on your code

E: 5: Assigning to function call which doesn't return

Regards,
Martin
 
D

Dave Angel

Tobias said:
Hi,
being new to Python I find remarkable that I don't see any side effects.
That's especially true for binding. First, it is a statement, so this
won't work:

if x = q.pop():
print x # output only true values

Second, methods in the standard library either return a value OR modify
the reciever, so even if assignment was an expression the above wouldn't
work.

Only it still wouldn't, because IF is a statement as well. So no ternary:

x = if True: 5 else: 7;

However there is one bit of magic, functions implicitly return None. So
while the following will both run without error, only one actually works:

x = 'foo'.upper()
y = ['f', 'b'].reverse()

Now I mentioned that the mutable types don't have functions that mutate
and return something, so I only have to remember that...

But I'm used to exploiting side effect, and sometimes forget this rule
in my own classes. IS THERE A WAY to have the following produce a
runtime error?

def f():
x = 5
# no return

y = f()

Maybe use strict ;)
There's a ternary operator. Check out the following sequence:

a = 42
b = 12 if a == 42 else 9
print a, b


Then try it again with a different value of a.

As for using = in an ordinary expression, I don't really miss it.
Python allows multiple assignments in the same statement, but they're
all to the same object. For the kinds of things where I would have done
an assignment inside an if or while (in C++), I usually can use a list
comprehension or somesuch.
 
A

Arnaud Delobelle

Dave Angel said:
Python allows multiple assignments in the same statement, but they're
all to the same object.

Unless they are to different objects:

a, b = 1, 2
 
D

Dave Angel

Arnaud said:
Unless they are to different objects:

a, b = 1, 2
You're right, of course. I was referring to the multiple '=' form, and
my statement was too general to be correct.

a = b = 42 is legal
a = (b=42) + 1 is not
 

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,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top