Cannot import the attribute from "abc.py" in Python

182 Views Asked by At

I have hello() in test/abc.py as shown below:

# "test/abc.py"

def hello():
    return "Hello"

Then, I import and call hello() from abc.py in test/main.py as shown below:

# "test/main.py"

from abc import hello

print(hello())

But, I got the error below:

ImportError: cannot import name 'hello' from 'abc'

So, I import abc.py and call abc.hello() in test/main.py as shown below:

# "test/main.py"

import abc

print(abc.hello())

But, I got another error below:

AttributeError: module 'abc' has no attribute 'hello'

Actually, I can import abc.py without error as shown below:

import abc

# print(abc.hello())

So, how can I import and call hello() from abc.py?

2

There are 2 best solutions below

0
Super Kai - Kazuya Ito On

Actually, you import the built-in module abc which means Abstract Base Classes to create abstract classes so don't create the file with the name abc.py. *You can see all built-in modules in Python Module Index which you cannot use as file names.

So, you should change abc.py to other name such as greeting.py as shown below:

# "test/greeting.py"

def hello():
    return "Hello"

Then, both work without error as shown below:

# "test/main.py"

from greeting import hello

print(hello()) # Hello
# "test/main.py"

import greeting

print(greeting.hello()) # Hello

In addition, importing def.py below gets SyntaxError: invalid syntax error because def is a reserved word to define functions. *You can see all reserved words in 2.3.1 Keywords and don't use abcdef's abc and def as file names:

import def # Error
0
just a fellow coder On

Your problem here is the file name for "abc.py." This is already a file within the included core libraries that ships with python.

We can see from the docs that when you import the Abstract Base Classes library, your code matches the import statement, thus causing an issue.

# Change "abc.py" to "something.py" or anything that won't conflict with core libs

# "test/something.py"

def hello():
    return "Hello"

Here are some ways to import this function:

# "test/main.py"

from something.py import hello     # will import only that function
from something.py import *         # will import all functions from file



# If you had multiple functions in the file, you can use only one line 
# without importing all other functions by using commas:

from something.py import hello, goodbye, seeYaLater



# THIS IS A TRICKY ONE:

import something

# When you import the file this way, you are going to need to
# reference the function with `something.hello()` which is a 
# real pain in the butt. Unless you have conflicting function 
# names across different files, I would avoid this one.


print(hello())

If you are ever unsure whether a file name is already taken by python, a modern code IDE such as Visual Studio Code has an extension called Pylance that will notify you of any collisions.

(Take a look at Semantic Highlighting and Automatic Imports from this article)

Hope this helps!