The None Value/Code in Automate the Boring Stuff - python

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

Related

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.

Why does get_name_by_addr return '' and org_by_addr return None?

I am currently testing one of my classes which sets variables with the help of pygeoip.
org_by_addr returns None when there is nothing found in the database:
seek_org = self._seek_country(ipnum)
if seek_org == self._databaseSegments:
return None
While the country_name_by_addr function returns an empty string.
This forces me to check if the return is None and then setting it to '' to have the variables uniformly.
Does anybody know, what the reason is to give different returns when there is no entry in the database?
Other than the obvious "variable uniformity", what is the point of changing the NoneType to an empty string? There is a reason why
bool ('') == bool (None) == False
In my opinion this is a stylistic difference. However, when a package has different return types like this, it can hint several things:
-if the function returns None, you can probably guess that the function would return an instanced object if a match was found in the database.
-if instead of returning None, the function returns an empty string, you can at least expect the output of that function to return a valid string when an entry is found in the database.
-if the function returns 0 instead of None, you can probably guess that the function would return a number of some sort if an entry was found in the database
So really it's mostly about informing the user in some way about what a valid return type would be.
My final suggestion would be to do away with the traditional thought of "types" when using Python. By that I mean the C philosophy of typing. In python there is a reason that you can say:
if result:
#some code
And have it be valid across several different "types".

Is returning 'None' for Python function ever a good idea?

The question is in the title...
I'm in a process of learning Python and I've heard a couple of times that function returning None is something you never should have in a real program (unless your function never returns anything). While I can't seem to find a situation when it is absolutely necessary, I wonder if it ever could be a good programming practice to do it. I.e., if your function returns integers (say, solutions to an equation), None would indicate that there is no answer to return. Or should it always be handled as an exception inside the function? Maybe there are some other examples when it is actually useful? Or should I never do it?
This just flat-out isn't true. For one, any function that doesn't need to return a value will return None.
Beyond that, generally, keeping your output consistent makes things easier, but do what makes sense for the function. In some cases, returning None is logical.
If something goes wrong, yes, you should throw an exception as opposed to returning None.
Unfortunately, programming tends to be full of advice where things are over-generalized. It's easy to do, but Python is pretty good with this - practicality beats purity is part of the Zen of Python. It's essentially the use case for dict.get() - in general, it's better to throw the exception if a key isn't found, but in some specific cases, getting a default value back is more useful.
def abc():
print 1
return None
print 2
is the same as
def abc():
print 1
return
print 2
or even
def abc():
print 1
All functions that don't return something return None. One very important use case of returning None is when you want to say "terminate this function" without having to nest a bunch of ifs.
It's a little complicated.
It comes down to cases here:
A function that merely mutates its object's state doesn't return anything (returns None). For example, given a list called L: L.sort(); L.append("joe")
Other functions create a new object or a new copy of an object, and return it without mutating the original list. Consider: sorted(L) ; y = L + [1,2,3]
It's generally bad form to return None meaning "everything is fine."
If you have some kind of lookup/accessor, None means "the value of that item is None", and when it's not found you should throw the appropriate exception.
In most other cases, returning None is a little confusing.

Does this Python expression make sense?

I found this kind of expression several times in a python program:
if variable is not None:
dothings(variable)
It seems strange to me, and I think that it has no more sense than:
if variable:
dothings(variable)
Maybe I don't know Python enough, and the expression is explained somewhere?
variable could be 0, or False, or [], or (); be 'falsy' in other words, and then the if statement would be skipped.
See Truth testing for more detail on what is considered false in a boolean context.
In short, testing if variable is not None allows variable to be anything else, including values that would otherwise be considered False in a boolean context.
Some values are falsy, but are not None. You may still want to dothings() to those values.
Here are the things that are falsy in Python 2. (You may want to change the '2' in the URL to a '3' to get the values for Python 3, but it didn't change much.)
E.g.
i = 0
if i is not None:
print i # prints i
if i:
print i # prints nothing
In the google voice python implementation I came across this as well, their use was during a function call. The parameters are defaulted to "None" and then when the function is called they can check if the values are changed or the default.
I.E.
def login (user=None, password=None)
if user is None:
user = input('Please enter your username');
...
return <something>;
called by
login()
OR
login(user='cool_dude')
OR
any combination of user/password you wish.
Additionally your "update" of the logic implies that variable == true or false. That is not correct for all cases (it may work in some cases but I'm throwing them out, since it's not a general case). What you are testing by using the "NONE" logic is whether the variable contains anything besides NONE. Similar to what I was saying above, all the "login function" was doing was determining if the user passed anything, not whether the value was valid, true, etc.

Categories