I'm brushing up on my Python and I'm a little confused about something, the following code does not work as intended:
def a():
print "called a"
def b():
print "called b"
dispatch = {'go':a, 'stop':b}
dispatch[input()]()
When I type the word go into the console, I get "NameError: name 'go' is not defined", but when I type 'go' (with the quotes) it works fine. Is input() not returning a string? And if not, then shouldn't using str() convert the input to a string?
When I change the code to:
dispatch[(str(input())]()
I still get the same behaviour.
note: I'm using Python2.7 if it makes a difference.
Sorry if this is obvious, it's been a few years since I've used Python!
input() in Python 2.7 is equivalent to:
eval(raw_input())
Hence, you should use raw_input() in python 2.7 to avoid such errors, as it will not try to evaluate the input given.
Because you add in quotation marks, Python interprets this as a string.
Also, note that raw_input() will return a string, so there will be no point in calling str() around it.
Note that in Python 3, input() acts like raw_input() did in Python 2.7
You want raw_input(). input() evaluates the user's input as Python code.
Use raw_input(). input() is equivalent to eval(raw_input()), so when you type go without quotes, python tries to eval go and fails. With the quotes, it eval's the string (ie. returns it) which will work to index your dict.
raw_input will work in every case.
You can also use this:
def go():
print "called a"
def stop():
print "called b"
input()() # Equivalent to eval(raw_input())()
# OR
my_function = input()
my_function() # Might be easier to read
# Another way of doing it:
val = raw_input()
globals()[val]()
Related
In Python 2.7 both the following will do the same
print("Hello, World!") # Prints "Hello, World!"
print "Hello, World!" # Prints "Hello, World!"
However the following will not
print("Hello,", "World!") # Prints the tuple: ("Hello,", "World!")
print "Hello,", "World!" # Prints the words "Hello, World!"
In Python 3.x parenthesis on print is mandatory, essentially making it a function, but in 2.7 both will work with differing results. What else should I know about print in Python 2.7?
In Python 2.x print is actually a special statement and not a function*.
This is also why it can't be used like: lambda x: print x
Note that (expr) does not create a Tuple (it results in expr), but , does. This likely results in the confusion between print (x) and print (x, y) in Python 2.7
(1) # 1 -- no tuple Mister!
(1,) # (1,)
(1,2) # (1, 2)
1,2 # 1 2 -- no tuple and no parenthesis :) [See below for print caveat.]
However, since print is a special syntax statement/grammar construct in Python 2.x then, without the parenthesis, it treats the ,'s in a special manner - and does not create a Tuple. This special treatment of the print statement enables it to act differently if there is a trailing , or not.
Happy coding.
*This print behavior in Python 2 can be changed to that of Python 3:
from __future__ import print_function
It's all very simple and has nothing to do with forward or backward compatibility.
The general form for the print statement in all Python versions before version 3 is:
print expr1, expr2, ... exprn
(Each expression in turn is evaluated, converted to a string and displayed with a space between them.)
But remember that putting parentheses around an expression is still the same expression.
So you can also write this as:
print (expr1), (expr2), ... (expr3)
This has nothing to do with calling a function.
Here we have interesting side effect when it comes to UTF-8.
>> greek = dict( dog="σκύλος", cat="γάτα" )
>> print greek['dog'], greek['cat']
σκύλος γάτα
>> print (greek['dog'], greek['cat'])
('\xcf\x83\xce\xba\xcf\x8d\xce\xbb\xce\xbf\xcf\x82', '\xce\xb3\xce\xac\xcf\x84\xce\xb1')
The last print is tuple with hexadecimal byte values.
Basically in Python before Python 3, print was a special statement that printed all the strings if got as arguments. So print "foo","bar" simply meant "print 'foo' followed by 'bar'". The problem with that was it was tempting to act as if print were a function, and the Python grammar is ambiguous on that, since (a,b) is a tuple containing a and b but foo(a,b) is a call to a function of two arguments.
So they made the incompatible change for 3 to make programs less ambiguous and more regular.
(Actually, I think 2.7 behaves as 2.6 did on this, but I'm not certain.)
In Python 2.7 both the following will do the same
print("Hello, World!") # Prints "Hello, World!"
print "Hello, World!" # Prints "Hello, World!"
However the following will not
print("Hello,", "World!") # Prints the tuple: ("Hello,", "World!")
print "Hello,", "World!" # Prints the words "Hello, World!"
In Python 3.x parenthesis on print is mandatory, essentially making it a function, but in 2.7 both will work with differing results. What else should I know about print in Python 2.7?
In Python 2.x print is actually a special statement and not a function*.
This is also why it can't be used like: lambda x: print x
Note that (expr) does not create a Tuple (it results in expr), but , does. This likely results in the confusion between print (x) and print (x, y) in Python 2.7
(1) # 1 -- no tuple Mister!
(1,) # (1,)
(1,2) # (1, 2)
1,2 # 1 2 -- no tuple and no parenthesis :) [See below for print caveat.]
However, since print is a special syntax statement/grammar construct in Python 2.x then, without the parenthesis, it treats the ,'s in a special manner - and does not create a Tuple. This special treatment of the print statement enables it to act differently if there is a trailing , or not.
Happy coding.
*This print behavior in Python 2 can be changed to that of Python 3:
from __future__ import print_function
It's all very simple and has nothing to do with forward or backward compatibility.
The general form for the print statement in all Python versions before version 3 is:
print expr1, expr2, ... exprn
(Each expression in turn is evaluated, converted to a string and displayed with a space between them.)
But remember that putting parentheses around an expression is still the same expression.
So you can also write this as:
print (expr1), (expr2), ... (expr3)
This has nothing to do with calling a function.
Here we have interesting side effect when it comes to UTF-8.
>> greek = dict( dog="σκύλος", cat="γάτα" )
>> print greek['dog'], greek['cat']
σκύλος γάτα
>> print (greek['dog'], greek['cat'])
('\xcf\x83\xce\xba\xcf\x8d\xce\xbb\xce\xbf\xcf\x82', '\xce\xb3\xce\xac\xcf\x84\xce\xb1')
The last print is tuple with hexadecimal byte values.
Basically in Python before Python 3, print was a special statement that printed all the strings if got as arguments. So print "foo","bar" simply meant "print 'foo' followed by 'bar'". The problem with that was it was tempting to act as if print were a function, and the Python grammar is ambiguous on that, since (a,b) is a tuple containing a and b but foo(a,b) is a call to a function of two arguments.
So they made the incompatible change for 3 to make programs less ambiguous and more regular.
(Actually, I think 2.7 behaves as 2.6 did on this, but I'm not certain.)
I am trying to make a script in Python, that when executed, asks the user for a function name and prints the function .__doc__
For example:
>>> print abs.__doc__
abs(number) -> number
Return the absolute value of the argument.
The problem is, it doesn't work with raw_input. The following is my code and what happens when it gets executed.
Code:
f = raw_input("Your function: ")
print f.__doc__
Execution:
Your function: abs
str(object='') -> string
Return a nice string representation of the object.
If the argument is a string, the return value is the same object.
What am I doing wrong?
Well you ask to print the __doc__ of f and f is in this case something like 'abs'. So you call 'abs'.__doc__ which is the __doc__ of a string.
Now you can however query for a builtin function with:
func = getattr(__builtins__,f)
print func.__doc__
this will however only work for builtin functions. You can also look for globals() or locals() which are dictionaries storing the global and local variables respectively.
As others have said, your problem is trying to use the string reply from raw_input() as a function object. You could get the function object by calling getattr(), but you need to known which module it is in. OK, so you could go through the global namespace looking for it, but there is a much simpler solution, just use pydoc:
f = raw_input("Your function: ")
help(f)
In this case, abs is a method that you're querying the __doc__ on. The raw_input is converting the input value to a string, so what you're really executing the __doc__ on is a string.
You get the same results if you do this:
z = ''
print z.__doc__
Why doesn't this call print anything? I am using python 3.
The goal of the question is not to print something but to understand the language better.
I am looking for language rule(s) that tells how those triple quotes are supposed to be interpreted according to the language specification.
And if there is difference between different versions of specs, please state the difference.
def my_function(s):
"""size = s.size()"""
print "a"
size = len(s)
print size
return
my_function("abc")
If this is python 3. You should be using print("a") not print "a"
When i used parenthesis, removed quotes it worked.
def my_function(s):
print("a")
size = len(s)
print(size)
return
my_function("abc")
That obviously prints at least "a"; so my guess is that you have it running detached from standard output (e.g. as a daemon) somewhere.
I just installed Python 2.7.2 on Windows XP with the idea of learning how to program.
Several of the tutorial books I'm using give examples of print commands which, when I try them, I get different answers.
I expected both of these to return the same thing -
>>> print("Hello, World!")
Hello, World!
>>> print("Hello", "World")
('Hello', 'World')
>>>
I've tried searching around for answers, but I'm not even sure how to explain where I'm going wrong.
Since print is a statement in Python 2.x, you're getting expected behavior. (a,b) is a tuple, so print (a,b) will print it as a tuple.
On the other hand, print is a function in Python 3.x, so
print("hello world")
and
print("hello", "world")
will yield the same answer.
This is one breaking change when going from Python 2.x to 3.x. Understanding the difference is important. Type help() in your interpreter and then print. You will get different descriptions based on your Python version.
I'd suggest checking out this page, which describes in a quick and nice way what worked before and what works now.
In the first case, you are calling the print method passing "Hello World!" as an argument. In Python 2.7 you don't need the braces, so you could also write it as
print "Hello World!"
In the second case you create a tuple ("Hello", "World") and pass that one to print. Therefore the tuple is printed. You are not passing two parameters to print. You are passing just one tuple.
It is not what you think it is. It's one argument and it is a tuple.
x=("Hello", "World")
>>> type(x)
<type 'tuple'>
And the reason that it works like this is because print is not a function but a statement.
Note: In python 3 print is a function.
in Python 2.x, print is a statement and not function. Statements have no paranethesis
print 'Hello World'
That's a bit tricky and will change in Python 3. You can activate this behavior in python 2 by adding the following import at the beginning of your sctipt:
from __future__ import print_fuction
Then, print will become a function and you'll call it like this
print('Hello World')
The difference you see in your example is that ('Hello', 'World') is a tuple while ('Hello World') is a string.
As mentionned by the Python doc :
A tuple consists of a number of values separated by commas
There is no coma in ('Hello world') so it is not a tuple. But ('Hello world',) has a coma before the end of the paranthesis and is a tuple.
The parenthesis in ('Hello world') are valid but are not really useful here.
You sould be careful with this when getting started. Tuples are identified by comas not parenthesis. Except for () which is the empty tuple. As we say in french, "this exception is the confirmation of the rule"
The difference in those two lines:
print("Hello, World!")
-> One string is printed, is says 'Hello, World!'
print("Hello", "World")
-> Two strings are given and both are printed. First 'Hello' and then 'World'