AttributeError: module 'file2' has no attribute 'A' - python-3.x

I have two python files file1.py and file2.py while accessing file2 variables in file1 I'm getting the error
file1.py contains:
from file2 import A
B = 10
print(A+B)
file2.py contains:
def func():
------ # ignore this function
------ # ignore this function
if '__name__'=='__main__':
A = 20
Then getting error :
AttributeError: module 'file2' has no attribute 'A'
How to access variables in other python file which are under
if '__name__'=='__main__':

I do not believe you can import variables under
if '__name__'=='__main__':
If the python interpreter is running that module (the source file) as the main program, it sets the special name variable to have a value “main”. If this file is being imported from another module, name will be set to the module’s name.
if __name__ == “main”: is used to execute some code only if the file was run directly, and not imported.
Instead, check this out:
if __name__ == "__main__":
A=20
else:
A=30
Now when you import file2 and print A, A will be 30.

Related

Access class attributes from an imported module through input arguments

I have a class named TEST in a configuration file config.py as follows:
# file config.py
class TEST():
alpha = 0.05
and a file run.py from which I try to access attributes of the class TEST through input argument as follows:
# file run.py
import sys
import config
if __name__ == "__main__":
conf = sys.argv[1] # comes from input argument conf=TEST
obj1 = config.TEST() # this works
print(obj1.alpha) # prints alpha variable 0.05
obj2 = config.conf() # AttributeError: module 'config' has no attribute 'conf'
print(obj2.alpha)
By running it as python3 run.py TEST, it gives attribute error in obj2, as it cannot convert the conf variable to TEST and access the class TEST. Any idea how to solve this?
Problem fixed by using the getattr from this thread:
Calling a function of a module by using its name (a string)
The code modification is as follows:
# file run.py
import sys
import config
if __name__ == "__main__":
conf = sys.argv[1] # comes from input argument conf=TEST
obj1 = config.TEST() # this works
print(obj1.alpha) # prints alpha variable 0.05
obj2 = getattr(config, conf)() #
print(obj2.alpha) # prints alpha variable 0.05
which by running it python3 run.py prints the desired.

Importing an class and its functionalities from one file to another

I am basically working with python(beginner) on jupyter notebook and stuck on importing a python file into another python file.I am working on an assignment it has 2 files a , b while making a class in file 'a' and importing that file into b to test the function that i have implemented in class of file a but didn't get answer
I tried this line for importing file 'a' in 'b' like this but unable to import
To demonstrate you i created a little sample.
Both files are in the same directory.
# file: a.py
class A:
def printing_method(self):
"""this is the method that prints the output"""
print('Class A said: hello world')
# file: b.py
# import class A from module a
from a import A
class B:
def not_printing_method(self):
"""here we create an instance of the imported class A"""
a_instance = A()
# call the method of class B to print
a_instance.printing_method()
# Create an instance of class B
b_instance = B()
# Call the printing method of class A through the not printing method of class B
b_instance.not_printing_method()

Importing a function from a different folder for unit testing throws an error for an exterior function call

I'm new to unit testing, learning with unittest. I'm trying to run a unit test from a file in a separate tests folder, using import to bring in the function I want to test.
When I run the test, I get a FileNotFoundError. The error points to a file that the main.py file should open, but for the test, I'm only importing the function translate.
I've tried setting up an __init__.py file with __all__ = ["translate"] - no change.
Here's my file structure:
|
|--dictionary_app
| |--main.py
| |--data.json
|
|--tests
|--integration
|
|--unit
|--test_1.py
Code from main.py:
#Get data from a JSON file
data = json.load(open("data.json"))
def translate(w):
w = w.lower()
if w in data:
return data[w]
elif w.capitalize() in data:
return data[w.capitalize()]
elif len(difflib.get_close_matches(w, data.keys())) > 0:
yes_no = input("Did you mean {} instead? Enter Y if yes, or N if
no: ".format(difflib.get_close_matches(w, data.keys())[0]))
if yes_no == "Y":
return data[difflib.get_close_matches(w, data.keys())[0]]
elif yes_no == "N":
return "This word does not appear in the Archives."
else:
return "Query not understood."
else:
return "This word does not appear in the Archives."
def main():
#calls translate
This line in test.py produces the error:
from dictionary_app.main import translate
My results
FileNotFoundError: [Errno 2] No such file or directory: 'data.json'
I didn't expect the import to pull in the line opening data.json.
By doing this data = json.load(open("data.json")), you're assuming that the file data.json is in the current execution directory.
So, you need to be in the directory dictionary_app when you run your test.
A more convenient way to proceed is to resolve the path of data.json by using __file__ to get the directory of your script.
For example:
import os
current_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(current_dir, "data.json")
data = json.load(open(filename))

Python3 imports changes

I have a module that uses enums defined in the same package. I want to run it locally for self testing and also access it from other packages, but I can't get the import for the enum to handle both situations.
I have tried a blank _ _ init _ _.py (without the spaces) in both the sub and the proj directories, with no apparent change.
I have tried variations of python -m without success.
Here is the minimal code that shows my problems:
/my/proj
|----sub
| |---e1.py
| |---one.py
| |---two.py
|-p1.py
|-p2.py
----
$ cat /my/proj/sub/e1.py
from enum import Enum
class UsefulEnums(Enum):
ZERO = 0
----
$ cat /my/proj/sub/one.py
from e1 import UsefulEnums as E
def profound():
print('The value of {} is {}'.format(E.ZERO.name, E.ZERO.value))
if __name__ == '__main__':
profound()
/my/proj/sub$ python one.py
The value of ZERO is 0
----
$ cat /my/proj/sub/two.py
# note the dot before the module name. No other change from one
from .e1 import UsefulEnums as E
def profound():
print('The value of {} is {}'.format(E.ZERO.name, E.ZERO.value))
if __name__ == '__main__':
profound()
/proj/sub$ python two.py
Traceback (most recent call last):
File "two.py", line 1, in <module>
from .e1 import UsefulEnums as E
ModuleNotFoundError: No module named '__main__.e1'; '__main__' is not a package
----
$ cd /my/proj
/my/proj$ cat p1.py
import sub.one as a
if __name__ == '__main__':
a.profound()
/my/proj$ python p1.py
Traceback (most recent call last):
File "p1.py", line 1, in <module>
import sub.be1 as a
File "/home/esmipau/delete_me/proj/sub/one.py", line 1, in <module>
from e1 import UsefulEnums as E
ModuleNotFoundError: No module named 'e1'
----
/my/proj$ cat p2.py
import sub.two as a
if __name__ == '__main__':
a.profound()
/my/proj$ python p2.py
The value of ZERO is 0
When run from the 'sub' directory, one.py works as expected, two.py fails with a 'ModuleNotFoundError' error as detailed above.
When imported in parent code and run from the parent directory, two.py now works, and one.py fails with a different 'ModuleNotFoundError' error.
I would like a three.py in the 'sub' directory that uses the enums defined in e1.py, and which can be run locally for self testing etc, and can be included from external module not in the same directory.
--- edit for close as duplicate suggestions ---
This is not the same question as others that have been suggested such as Correct import and package structure now that __init__.py is optional as I require a way for one module to import another in the same directory regardless of whether the module is being executed locally or imported from another module.
I had simmilar issue and this solved it:
try creating __init__ file like this:
import my.proj.sub.e1
and then in file you want to use add:
from my.proj.sub import UsefulEnums as E
Given the structure :
/proj
|---/pkg
| |---> usefulEnums.py
| |---> usefulCode.py
|--> myProj.py
I want to be able to run usefulCode.py in self test mode and I want to import and use it in myProj.
$ cat proj/pkg/usefulEnums.py
from enum import Enum
class UsefulEnums(Enum):
ZERO = 0
$ cat proj/pkg/usefulCode.py
if __package__ is None:
# works with python <path/>tcp.py
from usefulEnums import UsefulEnums as E
else:
# works with python -m pkg.tcp
# or when imported by another module
from pkg.usefulEnums import UsefulEnums as E
# This works as well and appears more more portable and pythonic
# but the logic that makes it work is obtuse and fragile
# and it doesn't work if __package__ is None (even though it should!)
# from .usefulEnums import UsefulEnums as E
def profound():
print('The value of {} is {}'.format(E.ZERO.name, E.ZERO.value))
if __name__ == '__main__':
profound()
The main project code is as expected:
cat proj/myProj.py
from pkg.usefulEnums import UsefulEnums as E
import pkg.usefulCode as u
if __name__ == '__main__':
u.profound()
The above is the work around I am accepting as the answer to my stated question, but the reasoning eludes me.
I do not understand why the behavior of the 'dot' import does not work as expected when __package__ is not defined. Surely it always means import relative to the current package, and if no package is explicitly defined, then why doesn't it mean import from the same directory as the current module, which could be argued to be the currently default package?

Define Python class in separate file

# File 1
me = MongoEngine(app) # I want to use my instance of MongoEngine to define new classes like the example in File 2
# File 2
class Book(me.Document):
title = StringField(null=False, unique=True)
year_published = IntField(null=True)
How can i pass the instance me.Document as an Object definition when creating my new classes in a new file. It works if i put them in the same file?
I believe that the answer choosen as answer is not fully correct.
It seems that File1.py is your main script which is executed,
and File2.py is a module which contains a class you wish to use in File1.py
Also based on a previous question of the OP I would like to suggest the following structure:
File1.py and File2.py are located in the same direcory
File1.py
import MongoEngine
from File2 import Book
me = MongoEngine(app)
# according to the documentation
# you do need to pass args/values in the following line
my_book = Book(me.Document(*args, **values))
# then do something with my_book
# which is now an instance of the File2.py class Book
File2.py
import MongoEngine
class Book(MongoEngine.Document):
def __init__(self, *args, **kwargs):
super(Book, self).__init__(*args, **kwargs)
# you can add additional code here if needed
def my_additional_function(self):
#do something
return True
In File 2 perform import of the me object:
from file1 import me
class Book(me.Document):
pass
# ...
Just like any Python object in a file, me can be imported. You can do it like so:
import file1
class Book(file1.me.Document):
#Do what you want here!
Hope I have helped!

Resources