Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Organize objects using un-instantiated classes as namespaces?

I've built a module to hold all of the common selenium expected_conditions which are then referenced throughout various tests. (The selenium portion of this example is not important, just the fact that I have a 'catalog' of a few thousand items.)

# ec module
class EcHR(object):
    class sidemenu(object):
        hrfile: Clickable      = Clickable((By.ID, "sidemenu_HRFile"),       f"HR File")
        hrvistainfo: Clickable = Clickable((By.ID, "sidemenu_HRVistA Info"), f"HR VistA Info")
    class hrfile(__hr_search__):
        class actionmenu(__hr_search__.actionmenu):
            add: Clickable       = Clickable((By.ID, "NewHireLink"), f"Add {BUTTON}")
            personnel: Clickable = Clickable((By.ID, 'setEmpType'), f"Personnel Filter {DROPDOWN}")
            status: Clickable    = Clickable((By.ID, 'setStatus'), f"Status {DROPDOWN}")
            configure: Clickable = Clickable((By.ID, "configureLinkGen"), f"Configure {BUTTON}")
            reports: Clickable   = Clickable((By.ID, 'Reports'), f"Reports {BUTTON}")
            class addmenu(object):
                employee: Clickable = Clickable((By.ID, f'Employee'), f"Add->Employee {BUTTON}")

Sample reference to a given item in the ec module.

import ec

    # navigation helper method for a given page
    def do_hrfile_nav(self):
        self.clickbutton(ec.EcHR.sidemenu.hrfile)

This works great; I can trace the usage of each object while still providing readability context for what the object is.

self.clickbutton(ec.EcHR.sidemenu.hrfile) tells the reader we are clicking on the sidemenu item hrfile on the HR page. This is important to distinguish from the ec.EcHR.hrfile which is a different set of objects.

My question: Is there a better/cleaner way to organize these objects? I'm using classes that never get instantiated. (which somehow feels awkward for reasons I can't articulate) These classes act solely as a means to reference them in an organized way. Perhaps some sort of lightweight data object that has class-like structure? (am I over thinking things?)

like image 520
Marcel Wilson Avatar asked Jan 18 '26 07:01

Marcel Wilson


1 Answers

I've got some ideas. It may be useful.

How about using functions as namespaces?

@namespace
def EcHR():
    @namespace
    def sidemenu():
        hrfile: Clickable = Clickable((By.ID, "sidemenu_HRFile"), f"HR File")
        return locals()

    @namespace
    def hrfile():
        @namespace
        def actionmenu():
            add: Clickable = Clickable((By.ID, "NewHireLink"), "Add {BUTTON}")

            @namespace
            def addmenu():
                employee: Clickable = Clickable(
                    (By.ID, f"Employee"), "Add->Employee {BUTTON}"
                )
                return locals()

            return locals()

        return locals()

    return locals()

I've changed every class to a function. And every function must be decorated with namespace decorator and must return locals() or any dict with custom key, val mapping.

Here's NameSpace class and namespace decorator.

from functools import reduce

class NameSpace:
    def __init__(self, name):
        self.__name__ = name

    def __str__(self):
        return "{}".format(self.__name__)

    def __repr__(self):
        return "NameSpace({})".format(self.__name__)

    def __call__(self):
        pass

def namespace(func):
    return reduce(
        lambda ns, kv: setattr(ns, kv[0], kv[1]) or ns,
        func().items(),
        NameSpace(func.__name__),
    )

The namespace decorator runs the decorated function and transforms the returned dict into a NameSpace instance.

How to access objects?

print(EcHR.sidemenu.hrfile)
print(EcHR.hrfile.actionmenu.addmenu.employee)
like image 117
Nizam Mohamed Avatar answered Jan 19 '26 19:01

Nizam Mohamed



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!