how to import class object in python from another file - python-3.x

Suppose I have a directory with files classfile.py and a test_classfile.py
here's classfile.py
class Student:
def __init__(self, fname, lname):
self.firstname = fname
self.lastname = lname
def printname(self):
return (self.firstname + self.lastname)
if __name__ == '__main__':
s = Student('John', 'Doe')
What I'd like to do is import just the object s
into the test_file.py
something like this,
from dir.classfile.Student import s
def test_classfile():
assert str(s.printname()).isalpha()
I get the following error
ModuleNotFoundError: No module named 'dir.classfile.Student'; 'dir.classfile' is not a package

As it is said 'dir.classfile' is not a package. If your .py files are both in the same directory, you just do 'import classfile'. Suppose the classfile.py was in the different directory, you would have to do the following:
import os.path
path_to_mods = os.path.abspath('path/to/classfile')
sys.path.insert(0, path_to_mods)
import classfile
You cannot import from 'Student' - this is an object. But you can import Student like this:
from classfile import Student
Also you cannot import instance of the class which is s. You should import the object like it it said above and then create an instance of it.

Related

Is it possible to make a module available as an import from another module?

I'm refactoring some code and have moved around some files. But for backwards compatibility, I would like to make all of my modules keep their old import paths.
my file structure is as follows
--| calcs/
----| __init__.py
----| new_dir
------| new_file1.py
------| new_file2.py
What do I need to do ensure that I can use an import like
import calcs.newfile1.foo
# OR
from calcs.newfile1 import foo
I have tried a few methods of adding the imports to the top level __init__.py file. As is reccommended here
But while this seems to allow an import such as import calcs.newfile1, An import such as import calcs.newfile1.foo raises ModuleNotFoundError: No module named calcs.newfile1
I expect that I need python to recognize calcs.newfile1 as a **module **. At the moment it seems to just be importing it as a class or other object of some sort
The only way i know how to do it is by creating a custom import hook.
Here is the PEP for more information.
If you need some help on how to implement one, i'll suggest you to take a look at the six module,
here
and here
Basically your calcs/__init__.py will become like this:
''' calcs/__init__.py '''
from .new_dir import new_file1, new_file2
import sys
__path__ = []
__package__ = __name__
class CalcsImporter:
def __init__(self, exported_mods):
self.exported_mods = {
f'{__name__}.{key}': value for key, value in exported_mods.items()
}
def find_module(self, fullname, path=None):
if fullname in self.exported_mods:
return self
return None
def load_module(self, fullname):
try:
return sys.modules[fullname]
except KeyError:
pass
try:
mod = self.exported_mods[fullname]
except KeyError:
raise ImportError('Unable to load %r' % fullname)
mod.__loader__ = self
sys.modules[fullname] = mod
return mod
_importer = CalcsImporter({
'new_file1': new_file1,
'new_file2': new_file2,
})
sys.meta_path.append(_importer)
and you should be able to do from calcs.new_file1 import foo

How to import one class and method instead of complete package from one file which is in A package to another Package In Python

Hello everyone please help as I am new to python and I want to know that how I can Import one class from one package to another package
eg:-
In Package A file name is func1.py
Now I want to import only one class lets GoodStudent in another package B in file func2
I have used this in the func2.py file from a package.func1 import GoodStudent but it's giving me o/p of both the class and function.
func1.py
def sum(x, y):
print(x + y)`enter code here`
sum(20,40)
class GoodStudent:
def __init__(self, location, name, age,xyz):
self.location = location
self.name = name
self.age = age
def GoodStudentInformation(self):
print("Name:{}".format(self.name))
print("Age:{}".format(self.age))
def GoodEmployeeInformation(self):
print("xyz:{}".format(self.xyz))
gs = GoodStudent('A', 'B', 7, 'QWERY')
gs.GoodStudentInformation()
gs.GoodEmployeeInformation()
class Employee:

import module in Class, but NameError when using module in class method

In my python script, I'm trying to import module in class and use the imported module in the class method.
class test:
import urllib.parse
def __init__(self, url):
urlComponents = urllib.parse.urlsplit(url)
Howerver, when I try to use the test class, such as
test("http://test.com")
I get the error:
NameError: name 'urllib' is not defined
Why import statement in class body do not take effect?
I use python 3.8.1 in windows 10.
The import statement performs a name binding, but names inside the class scope are not directly visible inside methods. This is the same as for any other class name.
>>> class Test:
... a = 2 # bind name on class
... def get_a(self):
... return a # unqualified reference to class attribute
...
>>> Test().get_a()
NameError: name 'a' is not defined
You can refer to any class attribute either through the class or the instance instead. This works for imported names as well.
class test:
import urllib.parse
def __init__(self, url):
# V refer to attribute in class
urlComponents = self.urllib.parse.urlsplit(url)
Note that there isn't any advantage to binding a module inside a class, with the exception of hiding the name from the global scope. Usually, you should import at the global scope.
import urllib.parse
class test:
def __init__(self, url):
# V refer to global module
urlComponents = urllib.parse.urlsplit(url)
It was self.urllib.parse that you were missing.
If you really want to import a module inside a class you must access it from that class:
class Test:
import urllib.parse as ul
def __init__(self, url):
urlComponents = self.ul.urlsplit(url)
t1 = Test("www.test.com")
print(t1)
Result : <main.Test at 0x5029>

Python 3 import class from subfolder problem

I have a strange problem regarding import classes from subfolders.
I'm using Python 3.6, therefore an __init__.py should be not required in the subfolders.
I have the following file structure:
root
├── script.py (main)
└── custom
├── class1.py
└── class2.py
This is script.py:
from custom.class1 import Class1
from custom.class2 import Class2
if __name__ == '__main__':
cl1 = Class1()
cl2 = Class2()
This is class1.py:
class Class1():
def __init__(self):
print('Class1')
if __name__ == '__main__':
cl1 = Class1()
This is class2.py, which imports also class1:
from class1 import Class1
class Class2():
def __init__(self):
cl1 = Class1()
print('Class2')
if __name__ == '__main__':
cl2 = Class2()
And now the problem:
It works without error, when i am running python class1.py in the custom subfolder.
It works without error, when i am running python class2.py in the custom subfolder.
But when i am running python script.py in the root folder, i get the following error:
Traceback (most recent call last):
File .... in <module>
from custom.class2 import Class2
File .... line 1, in <module>
from class1 import Class1
ModuleNotFoundError: No module named 'class1'
How can this be fixed in a way, that the scripts in the custom subfolders can be run on its own and also the script in the root folder works?
The problem is that you are running custom.class2 inside of script.py, which means while running custom.class2, you are still in the root directory.
To fix this, you should replace from class1 import Class1 from class2.py with from custom.class1 import Class1.
If you need to be able to run the file from any working directory, you may replace it's contents with this:
import os
import sys
path = os.path.abspath(os.path.dirname(__file__))
if not path in sys.path:
sys.path.append(path)
from class1 import Class1
class Class2():
def __init__(self):
cl1 = Class1()
print('Class2')
if __name__ == '__main__':
cl2 = Class2()
The code adds the file's path in to the sys.path list, which holds different paths from which you can import modules.

Dynamically import in python through a Dictionary

I need to import modules using a dictionary, I would like to loop through the dictionary and import it. For example
items = {
'Initial_Load': 'initial_load',
'Disclaimer': 'disclaimer_tests',
'Menu': 'menu_tests'
}
Those items should convert into
from Inital_Load import initial_load
from Disclaimer import disclaimer_tests
from Menu import menu_tests
Is it even possible?
This uses importlib.import_module to import the module, then getattr to resolve the name from that modules namespace:
from importlib import import_module
def import_dict(d):
result = {}
for module_name, attr_name in d.items():
module = import_module(module_name)
result[attr_name] = getattr(module, attr_name)
return result
import_dict({"math": "sqrt"})["sqrt"](4)
# 2.0

Resources