print function not printing appropriate output using eval - python

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.

Related

How can I use Python's exec() and eval() to execute arbitrary code AND return a value afterwards?

I'm looking for a function that will let me execute code passed as a string, but also return a value upon completion. I have found Python's exec and eval, each of which manage to do a part of what I want:
exec lets me execute some lines of code which I pass as a string: print to the console; set or change variables; write to files etc.
eval lets me evaluate a single expression and returns the value of this expression.
However, the functionality I want is to combine these: with a single function call, I want to execute some arbitrary code, and then return a value, which might be dependent on the code executed.
To contextualise, I want to modify the in-built Pickle __reduce__ method so that I can execute some code in the background while the object un-pickles. However, at the end of that code execution, I still want to return the original object that was pickled.
Pickle's __reduce__ has to return a function which is used to reassemble the object on un-pickling, so I want a use of eval and exec that lets me combine their usage into a single function call.
As an example, my code might look something like this:
def __reduce__(self):
code = """with open("flag.txt", "w") as f:\n\tf.write("A flag I have left!")\ndict()"""
return exec, (code, ), None, None, iter(self.items())
The odd return formatting is a quirk of Pickle. The oddly formatted code string should do this:
with open("flag.txt", "w") as f:
f.write("A flag I have left")
dict() # I'm trying to get the intepreter to 'evaluate' this final line
However, this doesn't work, as exec just does nothing with this final line, and returns None. If I swap, and use eval instead, then I get an error too, as eval can't do anything with the lines above.
I ave tried using the in-built compile method, but this doesn't actually seem to help because eval still won't evaluate compiled execution code.
I also see that this problem has popped up elsewhere on SO (here and here) but I'm unsatisfied with the answers provided, because they involve defining new functions, which are then useless in the context of getting Pickle to execute them on un-pickling, where the interpreter is naive of their definition.
Is there any way to neatly combine these expressions to achieve arbitrary execution as well as returning a value?
The best solution I could find to this problem is one based on some code from Yannic Kilcher.
You can combine the functions like this:
eval("exec(exec_code) or to_return")
eval will always try to return the value of the expression you have passed. If you pass a conditional expression, like the one above, then it will try and evaluate each part in turn to find the value of the whole conditional. As such, it will run your exec code, achieving what you need there, and then, finding that it evaluates to None, will return whatever the value of to_return is, because of the or. Therefore, if you make to_return your dictionary object constructor, then your code will run the exec statement first upon un-pickling, and then return a dictionary object as intended.

Event generated by a function call?

i'm trying to update a default value in a combobox, after a function is called successfully, how could i do that?
my basic idea is this.
if xfunc return True : widget.set(updated_value)
return is a keyword that is used to return objects during runtime in a function, meaning if you write the word 'return' anywhere in the function (main or otherwise): the compiler will try to end the function with whatever follows as the return type. Therefore, when writing if statements: in your mind try to replace the function call 'xfunc()' with whatever you think it will return, and test to see if it is equal ('==') with the return you want ('True')
However, the job of a if-statement is to test if something is True. Therefore if xfunc() == True: would be redundant (as pointed out by all or None), so we can simplify this statement to if xfunc():
ex:
if xfunc():
#run success code here

Difference between print(<variable_name>) and <variable_name> in python shell?

When i was going through the codes i found an interesting thing, if we initialize a variable in python shell, and we print that variable we get the value, if we use type the variable and press enter we get the same value. I could't figure out the reason behind it?? Can anyone help....
>a = 5
>print(a)
>5
>a
5
print will work in the shell AND in a script while giving the variable name is just a syntactic sugar for the shell.
The Python console is a Read Evaluate Print Loop (REPL). It first reads your input, evaluates it, prints any output, and repeats until you exit. It's a very common way to interact with a language, and exists for many many languages.
Another example of what you've observed is
>>> 1+2
3
Here the console evaluates 1+2 and prints the returned result. Try it with any function or expression.
print() works as expected because when it is evaluated, it does its own printing before returning None, just how any other function does all of its own code before returning to the console whatever will be printed. You could try this, for example
>>> type(print('test'))
test
<class 'NoneType'>
Here the console evaluates print('test'), which causes the first, manual print, and then automatically prints the return of the type call, resulting in the second line.
To answer your question, the difference between >>> print(a) and >>> a is that, in the first case, the console evaluates the print and has no return value to print, and in the second case, the console evaluates the expression and prints the result, which is a's value.

The None Value/Code in Automate the Boring Stuff

The text says the following:
In Python there is a value called None, which represents the absence of a value. None is the only value of the NoneType data type. (Other programming languages might call this value null, nil, or undefined.) Just like the Boolean True and False values, None must be typed with a capital N.
This value-without-a-value can be helpful when you need to store some-thing that won’t be confused for a real value in a variable. One place where None is used is as the return value of print(). The print() function displays text on the screen, but it doesn’t need to return anything in the same way len() or input() does. But since all function calls need to evaluate to a return value, print() returns None. To see this in action, enter the following into the interactive shell:
>>> spam = print('Hello!')
Hello!
>>> None == spam
True
Behind the scenes, Python adds return None to the end of any function definition with no return statement. This is similar to how a while or for loop implicitly ends with a continue statement. Also, if you use a return statement without a value (that is, just the return keyword by itself), then None is returned.
I think I understand what None is, but I am not understanding the code. Why is it that spam is then equal to None when it was assigned to be print('Hello!')? When I enter spam into the interactive shell immediately after the assignment it returns nothing. I get a feeling it is because the argument Hello! is immediately forgotten when print() is called and returns a value, but if I have defined spam to be the print() function with the argument Hello! passed through should it not always return Hello!?
To add to the comments and be more clear, your print() function printed 'Hello!' to the screen and returned None to the program. Printing and returning are not the same thing--printing is for the user, returning is for the program. The print goes to the screen only and (usually) cannot be further used by the program. The returned value can be stored in a variable, such as spam, and used further.
The distinction between printing and returning is important enough that the Python standard is that if a function prints something it should not return any value other than None, and if the function returns a value it should not print anything. This standard is not followed by many other languages (most notoriously C) and is not consistently followed in Python, but this distinction does help the clarity of Python. If you want to study this concept further, do a search on "side effects" in programming.
You are assigning spam to the print() function which doesn't return anything, aka None

'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.

Categories