I'm starting Comp Sci courses in Uni this coming fall (starting with zero programming knowledge), so I'm just starting to play around programming. I'm following a book and tried copy-pasting some code - but it doesn't work. Here's what I tried:
>>> def function(x):
return x+2
function(2)
SyntaxError: invalid syntax
The word "function" was highlighted. I'm confused because the very same example is used in the book and it appears to work but then I get that error on my end. What's going on here?
You need to separate the function definition from its execution. Also, Python is sensitive to whitespace at the beginning of lines. Try this (exactly):
def function(x):
return x+2
function(2)
or, in one line (which you should not do; see the style guidelines):
def function(x): return x+2; function(2)
or, in the Python shell:
>>> def function(x):
return x+2
>>> function(2)
4
Note the blank line between the function definition and its use. After you define the function, hit enter once to get the prompt back.
I'm assuming you meant to put Python in the title. Python has interesting syntax rules in that it actually counts white space as meaningful when parsing the program. What I mean is that having extra space, newlines, or tabs, etc. actually changes the meaning of the program. Double check the book example and make sure you have the exact same (tabs, new lines, and all) syntax written. It may look closer to this:
def f(x):
return x + 2
note the new line and tab. To call this function, on a separate line say:
f(5)
or replace 5 with whatever parameter you want.
edit:
so the full script should be:
def f(x):
return x + 2
f(2)
Try this:
def function(x):
return x+2
function(5)
In python, indentations are important. They are the {} of the python world.
You actually do not need to add extra whitespace before function(5) because python knows not to include it in the function definition because it is not indented. It is still good practice to add the extra blank line, but it is not strictly necessary.
This is for the users using Python 2.6.6 and IDLE 2.6.6.
Since Python interpreter is very much sensitive to whitespace and indentations, we need to separate the function declaration from the execution.
What you must be doing:
>>> def square(input):
output=input*input
return output
print square(5)
Output: SyntaxError: invalid syntax
Correct way to do it:
>>> def square(input):
output=input*input
return output
>>> print square(3)
9
Related
I'm learning Python and, so far, I absolutely love it. Everything about it.
I just have one question about a seeming inconsistency in function returns, and I'm interested in learning the logic behind the rule.
If I'm returning a literal or variable in a function return, no parentheses are needed:
def fun_with_functions(a, b):
total = a + b
return total
However, when I'm returning the result of another function call, the function is wrapped around a set of parentheses. To wit:
def lets_have_fun():
return(fun_with_functions(42, 9000))
This is, at least, the way I've been taught, using the A Smarter Way to Learn Python book. I came across this discrepancy and it was given without an explanation. You can see the online exercise here (skip to Exercize 10).
Can someone explain to me why this is necessary? Is it even necessary in the first place? And are there other similar variations in parenthetical syntax that I should be aware of?
Edit: I've rephrased the title of my question to reflect the responses. Returning a result within parentheses is not mandatory, as I originally thought, but it is generally considered best practice, as I have now learned.
It's not necessary. The parentheses are used for several reason, one reason it's for code style:
example = some_really_long_function_name() or another_really_function_name()
so you can use:
example = (some_really_long_function_name()
or
another_really_function_name())
Another use it's like in maths, to force evaluation precede. So you want to ensure the excute between parenthese before. I imagine that the functions return the result of another one, it's just best practice to ensure the execution of the first one but it's no necessary.
I don't think it is mandatory. Tried in both python2 and python3, and a without function defined without parentheses in lets_have_fun() return clause works just fine. So as jack6e says, it's just a preference.
if you
return ("something,) # , is important, the ( ) are optional, thx #roganjosh
you are returning a tuple.
If you are returning
return someFunction(4,9)
or
return (someFunction(4,9))
makes no difference. To test, use:
def f(i,g):
return i * g
def r():
return f(4,6)
def q():
return (f(4,6))
print (type(r()))
print (type(q()))
Output:
<type 'int'>
<type 'int'>
Is there a way to avoid "expected indent block" errors in Python without adding pass to a function?
def exclamation(s):
# s += "!!!"
# return s
print exclamation("The indented horror")
The above code results in an error on line 5. Yes, remove the comments and the code works fine. However, in debugging stuff I often find myself in a similar situation. Is this just a hang-up of the off-side rule and something I need to get used to or are there ways around this?
There has to be something within your function definition to avoid a SyntaxError.
The issue is that the interpreter will effectively ignore comments during parsing, and so while to a human it might look like something is there, to the parser it is empty.
As jonrsharpe has pointed out in a comment, you can use docstrings to "comment out" your code and have it still work. This is because the docstring is, in effect, a normal string. As such this will be parsed and won't cause a SyntaxError. To take your example code it would look like:
def exclamation(s):
'''s += "!!!"
return s'''
# This should print None as nothing is now returned from the func
print(exclamation("The indented horror"))
Here the goal is to call a global function as a decorator.
#coding: utf-8
def Test(method_to_decorate):
print 'Decorator'
def wrapper(self):
return method_to_decorate(self)
return wrapper
class Smth(object):
def Test(self):
print 'NOT a decorator!'
a=globals()['Test']
##globals()['Test'] --> SyntaxError
#a # works fine
def Fun(self):
print "Smth.Fun()"
l = Smth()
l.Fun()
Using the uncommented approach works fine while #globals()['Test'] gives SyntaxError. Why? I'm quite sure Test exists in globals().
The thing after # must be a function accepting another function as one of its arguments, am I right? globals()['Test'] is such a function, isn't it? Then, in my opinion, #globals()['Test'] must be correct (logically correct).
Edit
This works as expected:
def Ex(*args):
print 'Ex({})'.format(args)
globals()['Ex']('hello') # just calling a function
While a decorator is used, a function is called. We can call functions as above but can't use a decorator like this. Maybe this is some sort of a Python bug or logic misorganisation?
It's a SyntaxError because Python's grammar explicitly does not allow that; the tokens on the right of # are not an expression. 1 Instead, valid syntax is:
decorator: '#' dotted_name [ '(' [arglist] ')' ] NEWLINE
(A phrase enclosed in square brackets ([ ]) means zero or one occurrences (in other words, the enclosed phrase is optional).) 2
Following from the above, you can get this to work by converting globals()['Test'] to a dotted name. The following examples should work:
g = globals()
#g.get('Test')
def Fun(self):
pass
x = globals()['Test']
#x
def Fun(self):
pass
Or, as you noticed, you can just skip the syntactic sugar and decorate manually, which is probably the least bad option.
Because the Python parser isn't designed to recognize an index access as part of decorator syntax. Consider writing a separate function that accesses globals() instead.
I have recently noticed that some people mark the end of indented code blocks with the pass keyword, such as:
def f():
for i in range(10):
do_something(i)
pass
pass
I don't understand why. Are there any advantages?
I know the pass keyword does nothing and it is the equivalent of { } in other languages. My question is more related to a convention. For example, maybe people like to have something marking the end of a long code block.
Do you think Python's indention-sensitive grammar is harmful?
If your answer is "no",
then using pass to mark an end does nothing but clutter the cleanness
brought in by Python's indention sensitive grammar.
If your answer is "yes",
then using pass to mark an end is a workaround for the ambiguity
brought in by Python's indention sensitive grammar.
In Python, there is no {} and end, but semantic white spaces.
For example, consider the following Ruby code:
def f
for i in 0...10
i = i * 2
print(i)
end
end
And the equivalent Python code:
def f():
for i in range(10):
i = i * 2
print(i)
With one wrong keystroke (TAB):
def f():
for i in range(10):
i = i * 2
print(i)
The above code is also valid.
To avoid this kind of mistakes, we can use pass for end in Python:
def f():
for i in range(10):
i = i * 2
print(i)
pass
pass
With one wrong keystroke (TAB):
def f():
for i in range(10):
i = i * 2
print(i)
pass
pass
Python will refuse to work:
IndentationError: unexpected indent
However, python will not always catch unintended indentation even with pass.
Suppose we intend to write:
def g():
for i in range(10):
i = i * 2
pass
print(i)
pass
With one wrong keystroke (TAB):
def g():
for i in range(10):
i = i * 2
pass
print(i)
pass
Python will not refuse to work.
But using pass still has two advantages:
It still provides visual hint.
If you think pass as the last clause of an indented block,
print(i) looks weird to you in the above code.
A decent editor/IDE will indent correctly if you typed pass.
For the second pass,
if f() is a top-level function,
and your code adheres to PEP8:
Surround top-level function and class definitions with two blank lines.
You may omit the second pass.
But PEP8 also said:
Extra blank lines may be used (sparingly)
to separate groups of related functions.
Thus I prefer pass.
There is no advantage. If the function has a body at all, adding pass does nothing. It doesn't even do anything if there is no body, except to help the parser know that the empty body was intentional.
In real-world code, it's usually better to use a docstring than pass to denote deliberately-empty code:
class MyExtraException(Exception):
"""Just another exception"""
Is there any advantages?
No.
Placing pass at the end of non-empty code blocks like that just wastes lines. Remember that pass is a do-nothing placeholder in Python; it should only be used when you need to fill in an empty code block.
If you would like some examples of when to use pass, see this SO question as well as this one.
I have always wondered why can't we use hyphens in between function names and variable names in python
Having tried functional programming languages like Lisp and Clojure, where hyphens are allowed. Why python doesn't do that.
# This won't work -- SyntaxError
def is-even(num):
return num % 2
# This will work
def is_even(num):
return num % 2
I am sure Sir Guido must have done this because of some reasons. I googled but couldn't manage to find the answer. Can anyone please throw some light on this?
Because hyphen is used as the subtraction operator. Imagine that you could have an is-even function, and then you had code like this:
my_var = is-even(another_var)
Is is-even(another_var) a call to the function is-even, or is it subtracting the result of the function even from a variable named is?
Lisp dialects don't have this problem, since they use prefix notation. For example, there's clear difference between
(is-even 4)
and
(- is (even 4))
in Lisps.
Because Python uses infix notation to represent calculations and a hyphen and a minus has the exact same ascii code. You can have ambiguous cases such as:
a-b = 10
a = 1
b = 1
c = a-b
What is the answer? 0 or 10?
Because it would make the parser even more complicated. It would be confusing too for the programmers.
Consider def is-even(num): : now, if is is a global variable, what happens?
Also note that the - is the subtraction operator in Python, hence would further complicate parsing.
is-even(num)
contains a hyphen ? I thought it was a subtraction of the value returned by function even with argument num from the value of is.
As #jdupont says, parsing can be tricky.
Oddly enough it is possible to have class variable names with hyphens using setattr(), not that you would want to. Here is an example:
class testclass:
pass
x = testclass()
setattr(x, "is-even", True)
getattr(x, "is-even")
True
This still fails:
x.is-even
File "<stdin>", line 1
x.is-even
^
SyntaxError: invalid syntax