How to build a class into a Python module - python

I have a class file fil1.py and in this file, there is only one class called f. I want to build this class file into a module for which I've tried organizing my files like this:
foo/
foo/
__init__.py
file1.py # where class resides
setup.py
README.md
LICENSE
In the __init__.py, I have one sentence:
from file1 import f
Then, when I publish on pypi and then install back to my local computer. When I try:
from foo import f
I got an error message:
ImportError: cannot import name 'f' from 'foo'
I also tried
import foo
foo.f
The error message was:
foo has no attribute f
I am not sure how to achieve what I want.

There is no such thing as a "class file" in Python. A file is a module, and modules may contain zero or more classes, functions, or valid python statements not enclosed in a class or function (which run just one time when the module is imported). That said, I think you want:
foo/file1.py:
class f:
[...]
foo/__init__.py:
from foo.file1 import f
then all of the following are valid (assuming foo is available on sys.path, which includes the current working directory automatically as the first entry):
import foo
import foo.file1
from foo import f
from foo.file1 import f
foo is a package (because it contains __init__.py) with one module called file1. Alternatively, you could use a relative import inside __init__.py:
from .file1 import f
but that can get messy and is usually not appreciated in larger projects.

To achieve the absolute import from the package foo, I did is move my class definition into py.py. See Using pip to install single class package without module.pyfile import.
root/
foo/
__init__.py # where class resides
setup.py
README.md
LICENSE
Then I can do
from foo import f #f is the class previously in the file1.py

Related

Python calling a method from a different file defined in a class

I am trying to write a unit test. My unit test file is test_file . My main code is in a file(main_file.py) which has a class defined and several methods.
All my files are in same dir, so my tree structure looks like :
├── main_file.py
├── __init__.py
├── test_file.py
In my main_file i have a class name my_class and has method send_request.
In my test file i am trying to import the method to use:
from main_file import send_request
and when i run my unit test (python test_file.py) or even using nosetests it keeps throwing error:
ImportError: No module named main_file
my init.py is just empty.
When you are importing a file, you need to import the CLASS and not just the method if it is inside of a class. So you would need to do:
from main_file import my_class
instead of importing the function within the class. Then when you call the class you can do something such as
my_class.send_request()
when you call the function in your new .py
As you know you could import all of the classes and modules from main_file by doing:
import main_file
from main_file import *
Which will get you all of the classes/functions as well, although that may not be what you're looking for.
Besides that I would make sure they're all in the same directory again, and if it still fails, I usually just save everything to my "downloads" folder. When all else fails, and then it works.
you have to import class to use the method
from main_file import my_class
from my_class import FUNCTION_NAME or from my_class import *

Custom Py Module: Intra Module Importing

I am creating a custom Python module that I wanted to work similarly to something like numpy where most of the functionality can be accessed by calling np.function() or what have you. However, in creating my submodules and __init__.py file, I think that I've run into a circular import reference. Here's what I'm trying to do and the error I'm seeing, any tips to help me get this working the way I envisioned are greatly appreciated:
Let's call the module "foobar" and say I have a folder named "foobar" on the path and in this folder are three py files: "__init__.py", "foo.py", and "bar.py".
An example of submodule 1, "foo.py":
import bar
class Foo():
def __init__(self):
pass
def runfunc(self):
bar.func()
An example of submodule 2, "bar.py":
import foo
def func():
f=foo.F()
An example of __init__.py:
import numpy
from foo import *
from bar import *
__all__ = ['foo', 'bar']
So what I perceive to be my issue is that when foo is imported, it imports bar, which imports foo, which creates a loop (in my mind). I am also confused as to the use of __init__.py if, when it is called and imports other modules they cannot see each other when executing (i.e. I need to import bar into foo even though __init__.py did this).
When I run something from a script trying to import the entire module, I get the error in bar.py "ImportError: cannot import name foo". I am actually also having this issue elsewhere in the same module where I have a file with the base class "Base" and the extended class "Extended" where base.py needs to import extended.py so it can spawn instances of the expanded class and extended.py needs to import base.py so it can inherit the class.
Thanks for any help in advance!

Python submodule in the same file as module

If I currently have a file that is importing:
from foo import f0
from foo.bar import f1
I can create a file foo.py with a function f0 in it to satisfy the first import.
Is there any way to satisfy the second import from within that same file foo.py?
I just wanted to do that same thing. I only found this question, without an actual answer. So, here's what I came up with as a solution:
import sys
def add_submodule(submod):
name = submod.__name__
sys.modules[__name__ + "." + name] = submod(name)
from types import ModuleType
class submod1(ModuleType):
class foo:
pass
class submod2(ModuleType):
class bar:
pass
add_submodule(submod1)
add_submodule(submod2)
In essence, you subclass types.ModuleType to define a module. You then add it manually to sys.modules below the namespace of the current module, as given by __name__.
This is a minimal solution. If one would want to move add_submodule() to a separate stand-alone module for re-usability, it would have to be expanded a bit:
One could not simply use __name__ as this would be the namespace where add_submodule() was defined in. This should work instead:
In the separate module:
def add_submodule(submod, parentname):
name = submod.__name__
sys.modules[parentname + "." + name] = submod(name)
In the actual module:
add_submodule(submod1, __name__)
add_submodule(submod2, __name__)
I fear there's no nicer way of getting the parent's name into the function, though.
Both cases can now be used like so:
In [1]: import submodtest.submod1 as sm1
In [2]: import submodtest.submod2 as sm2
In [3]: sm1. [TAB]
sm1.foo sm1.mro
In [3]: sm2. [TAB]
sm2.bar sm2.mro
EDIT: Pushed the above full example to my Github.
Create a directory called foo
Within this directory, have a file called __init__.py
This effectively creates a module called foo
In this file, store the functions you want bundled with foo
Create a subdirectory of foo, called bar.
Within this directory, have a file called __init__.py
This effectively creates a sub module foo.bar
In this file, store the functions you want bundled with foo.bar
No, you should create a directory named foo as a package.
Click here to read official documentation about The import system

How to create a python package with multiple files without subpackages

I am attempting to create a package (mypackage) that contains a few classes, but would like the classes contained in multiple files.
For example, I want class_a.py to contain a class named ClassA, etc...
Thus, I would like the following file structure:
.../mypackage
__init__.py
class_a.py
class_b.py
...
However, I would like to load and use the package as follows:
load mypackage
a = mypackage.ClassA()
What do I need to do (I assume in the __init__.py) file to make this possible. Currently, it operates using "mypackage.class_a.ClassA()"?
As mentioned, in your __init__.py for a class, use the following:
from class_a import ClassA
from class_b import ClassB
for the case of a file without a class, use the following:
from . import file_a
from . import file_b
or if you only want to expose specific methods of a file:
from .file_a import method_a
from .file_b import method_b
Make your __init__.py import all your ClassA, ClassB, etc from other files.
Then you'll be able to import mypackage and use mypackage.ClassA, or from mypackage import ClassA and use it as unqualified ClassA.
A bit of background.
An import foo statement looks for foo.py, then for foo/__init__.py, and loads the names defined in that file into the current namespace. Put whatever you need to be "top-level" into __init__.py.
Also, take a look at __all__ top-level variable if you tend to from mypackage import *.
In your __init__.py, add this:
from class_a import ClassA
from class_b import ClassB
del class_a
del class_b

Importing specific classes from a file located in a python package

I have a python package main and other_python_files which are like:
main/
__init__.py
lib.py
other_python_files/
__init__.py
test.py
Let lib.py contain a class called MyClass. When I do from main import lib.py and use MyClass inside test.py I get the error that MyClass is not defined.
I tried doing from main import MyClass inside the init file in the main directory but I still get the same error. What should I do to achieve importing a specific class from the lib.py file ?
You either have to import that class out of lib:
from main.lib import MyClass
Or use lib.MyClass in place of MyClass.
You can also import MyClass inside of the __init__.py file that's in main, which lets you import it the way you originally tried:
__all__ = ['MyClass']
from lib import MyClass
You can read about __all__ here: Can someone explain __all__ in Python?

Categories