What happens if I import an module or function that conflicts with an object defined in my local namespace?

Question

In the context of this exercise, what happens if I import a module or function that conflicts with the name of an object defined in my local namespace?

Answer

If you import a module or function that conflicts with the name of an object defined in your local namespace, then the object defined in your local namespace will overwrite the one that was imported. However, it will only overwrite if the object in your namespace is defined after the import statement in the code.

Example

from math import sqrt

print(sqrt(4)) # 2.0

# Defining it after the import statement will
# overwrite the function with the same name
def sqrt(n):
  return n * 100

print(sqrt(4)) # 400

If the conflict is with the module, you can avoid this by aliasing it to another name. To avoid function name conflicts, it is best to be aware of all the function names from the module and to name your local namespace functions differently.

10 Likes

In this exercise what the space() functionality?
Also couldn’t understand the result.

1 Like

The reference is not to a function called space(), but to a concept called namespaces. Namespaces refer to the spaces or locations within a script where a certain name will be recognized.

The outermost indentation level is the global namespace, and every variable or function defined there will be recognized and available to every function.

Each function has its own namespace, referred to as local to the function. Variables defined within the function are not recognized or available outside the function.

When a function needs a value it looks first in its local namespace. If it cannot find the value there, it looks in the global namespace.

x = 5

def find_x(b):    
    a = x * b    # looks for x in local namespace, cannot find it, so goes to global namespace to find x = 5
    return a

def my_x(b):
    x = 7
    a = x * b    # looks for x in local namespace, finds that x has here been defined as x = 7
    return a
    
    
print(find_x(2))   # prints 10

print(my_x(2))    # prints 14

print(x)     # prints(5) The global x is unchanged. The local value of x = 7 in the second function is invisible
12 Likes

‘builtin_function_or_method’ object has no attribute ‘sample’

numbers_b = random.sample(12, range(1000))

Don’t use from random import *, but rather simply import random.

(Note also that you have the parameters for random.sample() reversed.)

import random
numbers_b = random.sample(range(1000), 12)
print(numbers_b)

Output:

[921, 417, 744, 707, 408, 451, 970, 126, 939, 236, 119, 851]

If you must use from random import * (again, this is not recommended by most Python commentators), then you omit the “dot” notation, since you have explicitly imported all of the functions within the random module into your global namespace:

from random import *
numbers_b = sample(range(1000), 12)
print(numbers_b)

Output:

[33, 198, 843, 607, 661, 6, 255, 273, 59, 899, 235, 623]
3 Likes

why I can’t do this?

import random
numbers_b = random.sample(1, 1000, 12) # giving start point, endpoint, and then how many numbers I #want instead of using range?
print(numbers_b)

Traceback (most recent call last):
File “/Users/kasem007/Work/code_academy/test.py”, line 4, in
number_b = random.sample(1, 100, 12)
TypeError: sample() takes 3 positional arguments but 4 were given

random.sample takes two arguments, a sequence and an integer number specifying the length of the sample output list https://docs.python.org/3/library/random.html#random.sample

In your given example each item separated by a comma is treated as a different argument so there are more arguments than expected. This particular method does not use the arguments to create it’s own iterable, it has to be passed one as the first argument. You can’t use it in the way you did because it is not desgined to work like that.

You could pass it a potential sequence other than range, e.g.

random.sample((1, 2, 3, 4, 5, 6, 7, 8, 9, 10), 5)
x = [1] * 10  # equivalent to [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
random.sample(x, 10)

If you’re wondering why the error states there were 4 arguments rather than the given 3 it’s because it’s actually a method and the first argument is the object reference (usually self).