1

I have a parent class that provides abstract functions for manipulating hardware, and a directory full of classes that subclass this parent class, and provide hardware-specific implementation (e.g. x86 functions, ARM functions...). I am looking for a Pythonic way to import the files in the directory, and instantiate them.

At the moment the parent class is in the top level directory, and the files with the child classes in a subdirectory. This can be changed, for style or ease of implementation.

Is it preferable to load all the hardware-specific classes in the subdirectory by defining a list of them in a configuration file, and iterating over that to import them? Or would it be better (more Pythonic) to do it automatically with importlib? Or does it not matter?

2 Answers2

1

The basic idea of dividing the sub classes int different files and importing only what you need is very pythonic. Consider using a __init__.py file in your subclasses' folder with an import SubClass1, SubClass2, SubClass3, ...-command in it. Then you can just say in the main.py:

import folderOfSubClasses

Then the __init__.py file will be executed and you have the expected result.

I hope I could help you!

monamona
  • 1,195
  • 2
  • 17
  • 43
1

Build a folder structure like this one:

.
├── arm (i kept this one empty, see similar x86 folder)
├── hal
│   ├── flags.py
│   ├── __init__.py
│   └── registers.py
├── x86
│   ├── flags.py
│   ├── __init__.py
│   └── registers.py
└── 8086.py

Put your ARM modules inside arm folder, x86 modules in x86 folder and so on.

Put your hardware parent classes in a parallel folder, represented in the tree by the hal folder. Notice that you probably have specific modules for each arch (in respective folder) with the same names of generic modules in the hal folder (but this is only a suggestion).

Build your hardware in a file such as 8086.py in the parent folder. Sample of 8086.py code:

from x86 import Ax, Bx, ZF # only the classes you need

ax = Ax()
bx = Bx()

# build your remaining CPU...

Sample of hal/flags.py:

class ZeroFlag():
    pass

Sample of hal/registers.py:

class Register:
    pass

Sample of hal/__init__.py:

from hal.registers import Register
from hal.flags import ZeroFlag

Sample of x86/flags.py

from hal import ZeroFlag

class ZF(ZeroFlag):
    pass

Sample of x86/registers.py

from hal import Register

class Ax(Register):
    pass

class Bx(Register):
    pass

Sample of x86/__init__.py

from .registers import *
from .flags import *

Now in each arch the specific modules can inherit and customize generic classes from hal. At top folder modules, you import those specifics to build your CPU or whatever hardware you are making.

Notice the importance of __init__.py files. they turn the folders into packages. __init__ also run on package import, allowing you to specify all the package modules you want to make available to importer. Note also that this list does not force the importer to import all the names. It can specify only the wanted ones.

If you have lots and lots of files you can place code in the __init__.py files to automate the imports, instead of writing them all by hand.

progmatico
  • 4,714
  • 1
  • 16
  • 27