Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: find classes in module before class is defined

Tags:

python

I have a python class in a module, and I have a few methods within it that need to have a list of certain other classes within the same module. Here is how I'm doing it right now:

module.py

class Main:
  @staticmethod
  def meth1():
    for c in classes:
      #do something

  @staticmethod
  def meth2():
    for c in classes:
      #do something

class Class1:
  pass

class Class2:
  pass

class Class3:
  pass

classes = [Class1, Class3]

A few things I would like to improve:

  1. I'd like to put the classes list somewhere more prevalent. Ideally, either outside all classes, but at the top of the module file, or as a class attribute of Main, but outside of either meth1 or meth2. The purpose of that is to make it easier to find, if someone needs to add another class definition.
  2. If possible, I'd like to do this programmatically so I don't need to explicitly define the list to begin with. This eliminates the need for #1 (though I'd still like it to be prevalent). To do this, I need a way to list all classes defined within the same module. The closest I've been able to come is dir() or locals(), but they also list imported classes, methods, and modules. Also, I would need some way to identify the classes I want. I can do that just with an attribute in the classes, but if there's some more elegant way, that would be nice.

Is what I'm trying to do even possible?

like image 540
ewok Avatar asked Dec 19 '22 17:12

ewok


1 Answers

Personally, I would use a decorator to mark the classes that are important. You can place the list that will hold them at the top of the file where it will be noticable.

Here's a simple example:

# Classes are added here if they are important, because...
important_classes = []


def important(cls):
    important_classes.append(cls)
    return cls


@important
class ClassA(object):
    pass


class ClassB(object):
    pass


@important
class ClassC(object):
    pass

# Now you can use the important_classes list however you like.
print(important_classes)
# => [<class '__main__.ClassA'>, <class '__main__.ClassC'>]
like image 115
Don Kirkby Avatar answered Dec 21 '22 09:12

Don Kirkby