My aim is to get the user-defined classes only. Try the following things, But I get all classes. So pls suggest, how to get the user-defined classes only instead of all classes. In my case, iterates/loops approx 200 times for each file( I need only the first three items class A, Class B and Class C only). How to get the user-defined classes only.
File : identify_user_defined_class
import importlib
import inspect
file_list =["identify_user_defined_class_base"]
list_class =[]
dict_class = {}
aa = 0
for items in file_list:
module_name = importlib.import_module(items)
for class_name,class_obj in inspect.getmembers(module_name):
aa = aa 1
print("bbbbb", aa,class_name,class_obj)
if inspect.isclass(class_obj) and str(class_obj)[0:12] != "<class 'PyQt":
source, start_line = inspect.getsourcelines(class_obj)
list_class.append([start_line,class_name])
dict_class.update({class_name:class_obj})
list_class.sort()
File : identify_user_defined_class_base
from PyQt5.QtWidgets import *
class A(QWidget):
pass
class B(QWidget):
pass
class C(QWidget):
pass
CodePudding user response:
The simple solution is to compare the __module__
attribute of the class with the name of the imported module. This attribute specifies the module in which the class is defined, so it is sufficient to distinguish it from all other imported or built-in classes.
Thus, in your example, you can simply do:
if inspect.isclass(class_obj) and class_obj.__module__ == items:
...
However, although this might be good enough for your immediate use-case, it isn't a particularly robust solution. One obvious problem with it, is that it doesn't handle sub-classes very well. For example, consider a module like this:
from PyQt5.QtWidgets import QWidget
class BaseClass(QWidget):
def commomMethod(self):
...
class ClassA(BaseClass):
...
class ClassB(ClassA):
...
For your use-case, I presume you would want to include ClassA
and ClassB
, but not BaseClass
. However, not allowing this very common form of subclassing would probably be too restrictive for a system like this. So the usual solution is to define a special base-class that explicitly marks the classes you want to import. This would mean the above module would look like this:
from PyQt5.QtWidgets import QWidget
from mymodule import MarkerClass
class BaseClass(QWidget): ...
class ClassA(BaseClass, MarkerClass): ...
class ClassB(ClassA): ...
And your importer code would then look like this:
from mymodule import MarkerClass
...
if (inspect.isclass(class_obj) and class_obj is not MarkerClass and
issubclass(class_obj, MarkerClass)):
...
where MarkerClass
can just be an empty class definition, like this:
class MarkerClass: pass
This approach will be much more robust and easier to maintain in the long-run, and allows for much greater flexibility when designing the dynamically imported classes.