What are valid statements inside a python eval()? - python

I have tried
eval('print("hello world")')
eval('return 0')
which are both incorrect. Why are they invalid and what rules should I follow when using eval() (other than as little as possible)?

In Python, eval() evaluates expressions (something that results in a value). Both print and return are defined as statements (however in Python 3, print is actually a function call, which is an expression). In the case of executing statements, you need to use the exec statement instead.

eval() is used to evaluate a value of a varaible as a variable.
example:
var="Hello World!"
code="var"
print eval(code)
output should be:
Hello World!

Related

Is there a way to get the function parameters in the callee as the caller put it?

I want to achieve that calling foo(2*3) prints 2*3.
The reason is that I try to create a test framework for querying data files and I want to print the query statement with the assertion result.
I tried to get it work via the inspect module but I could not make it work.
In general, the answer is "no", since the value received by the function is the result of the expression 2*3, not the expression itself. However, in Python almost anything is possible if you really want it ;-)
For simple cases you could achieve this using the inspect module like this:
#!/usr/bin/env python3
import inspect
def foo(x):
context = inspect.stack()[1].code_context[0]
print(context)
def main():
foo(2 * 3)
if __name__ == '__main__':
main()
This will print:
foo(2 * 3)
It would be trivial to get the part 2 * 3 from this string using a regular expression. However, if the function call is not on a single line, or if the line contains multiple statements, this simple trick will not work properly. It might be possible with more advanced coding, but I guess your use case is to simply print the expression in a test report or something like that? If so, this solution might be just good enough.
Because the expression is evaluated before it is passed to the function, it is not possible to print out the un-evaluated expression.
However, there is a possible workaround. You can instead pass the expression as a string and evaluate it inside the function using eval(). As a simple example:
def foo(expr):
print(expr)
return(eval(expr))
Please note however that using eval is considered bad practice.
A better solution is to simply pass a string as well as the expression, such as foo(2*3, "2*3").

print function not printing appropriate output using eval

I am getting 2 different outputs using 2 similar commands:
>>> inp = 'print("hi")'
>>> print(eval(inp))
hi
None
>>> eval(inp)
hi
How to I make print(eval(inp)) print just 'hi'? Why is None printing as well?
So here's what happens when you do print(eval('print("hi")')):
eval() is called, with the argument 'print("hi")'
Accordingly, the code print("hi") is executed
"hi" is printed to the console
Having finished executing, print() returns None.
Having executed the code 'print("hi")', the eval() function records the return call of that function. Which was None.
Accordingly, eval() returns None, since that was the result of the code it ran.
The outer print() call is supposed to print whatever the eval() function returned. Now it looks like print(None).
None is printed to console.
tl;dr, print() is called two different times. Thus, two different things are printed: "hi" the first time, and None the second time.
If all you want is to print "hi", you can just do eval('print("hi")') - or you could do print(eval("hi")), since in this case eval() would return "hi" and that's what would be printed. In either of those cases you would only ever be executing one print statement.
Though, in general, please do not use eval() for anything. It's notoriously risky, prone to errors that can completely break your program, and there's nothing you can do with it that you can't do with the code you'd put inside it. The only feasible reason for using eval() would be to respond dynamically to user-generated code, which is a terrible idea because it allows code injections. The user shouldn't be able to do that.

'None' is not displayed as I expected in Python interactive mode

I thought the display in Python interactive mode was always equivalent to print(repr()), but this is not so for None. Is this a language feature or am I missing something? Thank you
>>> None
>>> print(repr(None))
None
>>>
It's a deliberate feature. If the python code that you run evaluates to exactly None then it is not displayed.
This is useful a lot of the time. For example, calling a function with a side effect may be useful, and such functions actually return None but you don't usually want to see the result.
For example, calling print() returns None, but you don't usually want to see it:
>>> print("hello")
hello
>>> y = print("hello")
hello
>>> y
>>> print(y)
None
Yes, this behaviour is intentional.
From the Python docs
7.1. Expression statements
Expression statements are used (mostly interactively) to compute and
write a value, or (usually) to call a procedure (a function that
returns no meaningful result; in Python, procedures return the value
None). Other uses of expression statements are allowed and
occasionally useful. The syntax for an expression statement is:
expression_stmt ::= starred_expression
An expression statement evaluates the expression list (which may be a
single expression).
In interactive mode, if the value is not None, it is converted to a
string using the built-in repr() function and the resulting string
is written to standard output on a line by itself (except if the
result is None, so that procedure calls do not cause any output.)
In Python, a function that does not return anything but is called only for its side effects actually returns None. As such functions are common enough, Python interactive interpreter does not print anything in that case. By extension, it does not print anything when the interactive expression evaluates to None, even if it is not a function call.
If can be misleading for beginners because you have
>>> a = 1
>>> a
1
>>>
but
>>> a = None
>>> a
>>>
but is is indeed by design
None represents the absence of a value, but that absence can be observed. Because it represents something in Python, its __repr__ cannot possibly return nothing; None is not nothing.
The outcome is deliberate. If for example a function returns None (similar to having no return statement), the return value of a call to such function does not get shown in the console, so for example print(None) does not print None twice, as the function print equally returns None.
On a side note, print(repr()) will raise a TypeError in Python.

python one-line if statement calling function if true

I'm using argparse.
def help():
parser.print_help()
sys.exit(0)
help() if (args.lock and args.unlock)
This gives me a syntax error. What is wrong with my if statement?
You are using a conditional expression: true_result if condition else false_result. A conditional expression requires an else part, because it has to produce a value; i.e. when the condition is false, there has to be an expression to produce the result in that case.
Don't use a conditional expression when all you want is a proper if statement:
if args.lock and args.unlock: help()

Why can't I "string".print()?

My understanding of the print() in both Python and Ruby (and other languages) is that it is a method on a string (or other types). Because it is so commonly used the syntax:
print "hi"
works.
So why doesn't "hi".print() in Python or "hi".print in Ruby work?
When you do something like "hi".print(), you are implying that the string object "hi" has a method print. This is not the case. Instead, print is a function that takes a string (or other types) as input.
Ruby does have a method Object#display (doc here), which sends a representation of the object to the current output stream, or one specified as an argument.
(I find that it's hard to work with in irb if I use ; at the end of a line to suppress the printing of the return value; if I do that, display's output isn't shown, even if I flush the stream.)
It's not a method on a string. Prior to Python 3, it was a statement (just like break or import), and you could use both print "hi" and print("hi"). From Python 3, it was replaced by a function, thus you can no longer use print "hi":
Print Is A Function
The print statement has been replaced with a
print() function, with keyword arguments to replace most of the
special syntax of the old print statement (PEP 3105).
Why should it work? String classes rarely have void print methods - and you would never need them, because the standard static print function can print those strings anyway. It is important to note: method(someObject) is not necessarily the same as someObject.method().
What do you propose str.print should do?
print to stdout? how about stderr? or a file? or a serial port?
Printing to stdout is really a special case but it's so ubiquitous that sometimes it can be overlooked.
Then we'd have to specify where str should print to every time we create a string?
At the very least we'd have to say
"foo".print(sys.stdout)
Hopefully that looks awful to you too. It's a confusion of responsibilities
print isn't a method on a string in Python (or in Ruby, I believe). It's a statement (in Python 3 it's a global function). Why? For one, not everything you can print is a string. How about print 2?
In case you are more happy to use a method rather than a statement in Ruby you can use the method display ("test".display) to achieve this or define a new method easily like
class String
def print
puts self
end
end
and use it like this
"test".print

Categories