What does it mean that `None` cannot be updated or assigned new values?

I have a question about “None”. This exercise says
" None is a special value in Python. It is unique (there can’t be two different None s) and immutable (you can’t update None or assign new attributes to it)."

So I thought it would be error

#sample code
aa = None
print(aa)
aa = “something”
print(aa)

#end of code
When I ran codes, The result was

None
something

I didn’t get error and I thought I did assign new attributes to “aa” which was “None”.

Why is None immutable ?

2 Likes

You didn’t update None (a value), you updated aa (a variable). Assignment goes from right to left across the assignment operator, =. (Some people like to indicate assignment in pseudocode with a left-pointing arrow to emphasize this.)

When you use =, you are assigning (some say binding) the value on the right to the variable on the left. You can do that as often as you’d like to.

What you cannot do is
None = any_value # This will raise a “cannot assign to a keyword” Syntax Error

You are not surprised by the result below, are you? It is the same thing.

a = 10  # An int is unique, immutable, and you cannot assign any attributes to it.
print(a)
a = 20
print(a)

Output:

10
20
6 Likes

All primitives are immutable since they are not objects. @patrickd314 (if I recall) posted a really good link a while back on this topic. Search the forums and it should come up.

1 Like

It wasn’t me. Some objects are immutable, many not, but none are “primitive”.

From the docs,

Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects

You’ll see references to “primitives” in Python here and there on the web, but those are simply references to those data types which are immutable and which are not containers. In the docs, if you search for the word “primitive”, you’ll get no hits defining a data type, certainly not one that is not an object. I believe that the old saw, “In Python, everything is an object” is true.

It is my understanding (not firsthand) that the “primitive” vs “object” distinction is important in Java, but it is not so in Python.

2 Likes

Roving from language to language there is a lot of blurring of the lines. This topic (primitives) really needs a definitive guide with tables that describes how different languages treat it.

I won’t attempt to argue that what is stated about Python, where everything is an object, is fact. But I run into confusion when I see something like this…

>>> type(1)
<type 'int'>
>>> isinstance(1, int)
True
>>> type(None)
<type 'NoneType'>
>>> isinstance(None, NoneType)

Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    isinstance(None, NoneType)
NameError: name 'NoneType' is not defined
>>> 
2 Likes

I could not agree more!

Yes, it appears that None’s status as a singleton means that NoneType is not available in the global namespace. I don’t really understand the reason. Majority opinion seems to be that the only way one should test for None is by means of is.

2 Likes

Oh I see. Thank you for your good explanation.

1 Like

As in,

def foo():
    pass
print (foo() is None)

or,

def bar(x):
    return 1 if x > 0 else -1 if x < 0
print (bar(0) is None)

Yeah, I know, this is silliness…

1 Like

As clear as can be . thanks

Hi, can someone explain to me the need to prefix “./” at the point of the code where i’ve commented the question? Am i correct in assuming it is redundant to do so?

import os

def make_folders(folders_list, nest=False):
  if nest:
    """
    Nest all the folders, like
    ./Music/fun/parliament
    """
    path_to_new_folder = "."
    for folder in folders_list:
      path_to_new_folder += "/{}".format(folder)
      try:
        print(path_to_new_folder)
        os.makedirs("./" + path_to_new_folder) #### Why is the "./" needed? It works fine even without it.
      except FileExistsError:
        continue
  else:
    """
    Makes all different folders, like
    ./Music/ ./fun/ and ./parliament/
    """
    for folder in folders_list:
      try:
        os.makedirs(folder)

      except FileExistsError:
        continue

make_folders(['Music', 'fun', 'parliament'], True)

From this exercise: https://www.codecademy.com/courses/learn-python-3/lessons/learn-python-function-arguments/exercises/default-arguments