user3438349
user3438349

Reputation: 67

Why is calling `import random; random.random()` throwing a TypeError?

I'm new to Python. I wrote a small script to generate ten random float values, but it keeps failing. Here's the script:

import random

for i in range(10):
  x = random.random()
  print x

and here's the error message:

TypeError: 'module' object is not callable'.

I can't see what the problem is. I'm pretty sure random exists!

My version is Python 2.7.6.

Upvotes: 0

Views: 1649

Answers (1)

jfs
jfs

Reputation: 414179

If you save the following code into random.py:

import random
print(__name__)
print(random)
print(random.random)

and run it then it prints something like:

random
<module 'random' from '/.../python/import/name-shadowing/random.py'>
<module 'random' from '/.../python/import/name-shadowing/random.py'>
__main__
<module 'random' from '/.../python/import/name-shadowing/random.py'>
<module 'random' from '/.../python/import/name-shadowing/random.py'>

i.e., both random and random.random refers to the same module -- your local random.py that shadows random module from the standard library.

Perhaps it works as follows:

  1. python -mrandom finds random.py in the current directory, imports it as random and and starts to run it as __main__.
  2. It sees import random and imports the cached module.
  3. print(random) prints the representation of the module object to stdout.
  4. print(random.random) looks up random name in random module. It finds it (the name refers to the module itself. And it prints it.

The solution is to avoid shadowing the names. Avoid shadowing the standard names for readability. And avoid shadowing 3rd-party names if you might use them in your code.

If the current directory is not in sys.path then it imports stdlib module:

import sys
sys.path.pop(0) # assume the script directory is the first in the Python path
import random
print(__name__)
print(random)
print(random.random)

Output

__main__
<module 'random' from '/usr/lib/python3.4/random.py'>
<built-in method random of Random object at 0x1aaf7f8>

Note: it is only for illustration. Avoid modifying sys.path in your scripts.

Upvotes: 1

Related Questions