How can I get a list of all classes within current module in Python?
Try this:
import sys
current_module = sys.modules[__name__]
In your context:
import sys, inspect
def print_classes():
for name, obj in inspect.getmembers(sys.modules[__name__]):
if inspect.isclass(obj):
print(obj)
And even better:
clsmembers = inspect.getmembers(sys.modules[__name__], inspect.isclass)
Because inspect.getmembers()
takes a predicate.
In Python, how do I get the list of classes defined within a particular file?
You can get both:
import importlib, inspect
for name, cls in inspect.getmembers(importlib.import_module("myfile"), inspect.isclass):
you may additionally want to check:
if cls.__module__ == 'myfile'
How do you get all classes defined in a module but not imported?
Inspect the __module__
attribute of the class to find out which module it was defined in.
How to list all functions in a module?
Use the inspect
module:
from inspect import getmembers, isfunction
from somemodule import foo
print(getmembers(foo, isfunction))
Also see the pydoc
module, the help()
function in the interactive interpreter and the pydoc
command-line tool which generates the documentation you are after. You can just give them the class you wish to see the documentation of. They can also generate, for instance, HTML output and write it to disk.
Python: get only classes defined in imported module with dir()?
Use the inspect
module to inspect live objects:
>>> import inspect
>>> import my_module
>>> [m[0] for m in inspect.getmembers(my_module, inspect.isclass) if m[1].__module__ == 'my_module']
That should then work, getting every class
defined within that my_module
.
Getting all class methods in classes in current file in Python?
On Python 3, calling inspect.ismethod
on an attribute of a class that happens to be a function will always be False, because it will just be a plain function. function.__get__
only returns a method object when accessed as an attribute of an instance.
If you want to get all "methods" of the class just use inspect.isfunction
.
>>> class A:
... def __init__(self): pass
...
>>> A.__init__
<function A.__init__ at 0x7fd524dd2f80>
>>> inspect.ismethod(A.__init__)
False
>>> inspect.isfunction(A.__init__)
True
>>> inspect.ismethod(A().__init__)
True
Get all class names in a Python package
inspect.getmembers()
works on objects, and you are passing in strings. Python doesn't know these strings contain filenames or will treat these filenames as modules to import.
You'd have to import the files for inspect.getmembers()
to work. Because you are working with files in the current directory, you should be able to just import them all:
import importlib
for x in onlyfiles:
module = importlib.import_module(x)
for name, obj in inspect.getmembers(module):
if inspect.isclass(obj):
print obj
Note that inspect.getmembers()
accepts a second argument, the predicate that lets you filter what the method returns. Instead of filtering manually, you could just use inspect.isclass()
as the predicate here:
for x in onlyfiles:
module = importlib.import_module(x)
for name, obj in inspect.getmembers(module, inspect.isclass):
print obj
Getting the list of classes in a given Python file
So to use importlib
similarly to how you're using imp
, you can look at this: Python 3.4: How to import a module given the full path?
and you get something like the following:
import importlib.machinery
import inspect
module = importlib.machinery.SourceFileLoader("a", './a.py').load_module()
class_members = inspect.getmembers(module, inspect.isclass)
Solution #1: Look up class statements in the Abstract Syntax Tree (AST).
Basically you can parse the file so that you can get the class declaration statements.
import ast
def get_classes(path):
with open(path) as fh:
root = ast.parse(fh.read(), path)
classes = []
for node in ast.iter_child_nodes(root):
if isinstance(node, ast.ClassDef):
classes.append(node.name)
else:
continue
return classes
for c in get_classes('a.py'):
print(c)
Solution #2: Look at imports and ignore import from statements.
This is more in-line with your current approach, but is a little jankier.
You can look for things imported by the file you're looking at and select out the import from statements (Python easy way to read all import statements from py module) and just make sure that none of the things imported show up later:
import ast
from collections import namedtuple
Import = namedtuple("Import", ["module", "name", "alias"])
def get_imports(path):
with open(path) as fh:
root = ast.parse(fh.read(), path)
for node in ast.iter_child_nodes(root):
if isinstance(node, ast.Import):
# We ignore direct imports
continue
elif isinstance(node, ast.ImportFrom):
module = node.module.split('.')
else:
continue
for n in node.names:
yield Import(module, n.name.split('.'), n.asname)
imported = set()
for imp in get_imports('a.py'):
imported_classes.add(imp.name[0] if not imp.alias else imp.alias)
Then you can just filter out the imported things you saw.
for c in class_members:
class_name, class_obj = c
member = c[1]
if class_name not in imported:
print(class_name)
Note that this currently doesn't distinguish between imported classes and imported functions, but this should work for now.
python - get list of all functions in current module. inspecting current module does not work?
EDIT 1: What I am trying to do is
def testall(arg):
return any(f(arg) for f in testfunctions)
def test1(arg):
#code here
# may call testall but wont call anyother test*
This works just fine:
def testall(arg):
testfunctions = [obj for name,obj in inspect.getmembers(sys.modules[__name__])
if (inspect.isfunction(obj) and
name.startwith('test') and name != 'testall')]
return any(f(arg) for f in testfunctions)
def test1(arg):
#code here
# may call testall but wont call anyother test*
In this case, testfunctions
isn't evaluated until testall
is called, so there's no problem here—by that time, all top-level module code (including the test1
definition) will have been evaluated, so testfunctions
will get all of the top-level functions. (I'm assuming here that testall
or test1
is being called from an if __name__ == '__main__'
block at the bottom of the module, or another script is doing import tests; tests.test1(10)
, or something similar.)
In fact, even if you explicitly named test1
and test2
, there would be no problem:
def testall(arg):
testfunctions = ('test1',)
return any(f(arg) for f in testfunctions)
def test1(arg):
#code here
# may call testall but wont call anyother test*
Again, test1
is already defined by the time you call testall
, so everything is fine.
If you want to understand why this works, you have to understand the stages here.
When you import a module, or run a top-level script, the first stage is compilation (unless there's already a cached .pyc file). The compiler doesn't need to know what value a name has, just whether it's local or global (or a closure cell), and it can already tell that sys
and inspect
and test1
are globals (because you don't assign to them in testall
or in an enclosing scope).
Next, the interpreter executes the compiled bytecode for the top-level module, in order. This includes executing the function definitions. So, testall
becomes a function, then test1
becomes a function, then test2
becomes a function. (A function is really just the appropriate compiled code, with some extra stuff attached, like the global namespace it was defined in.)
Later, when you call the testall
function, the interpreter executes the function. This is when the list comprehension (in the first version) or the global name lookup (in the second) happens. Since the function definitions for test1
and test2
have already been evaluated and bound to global names in the module, everything works.
What if you instead later call test1
, which calls testall
? No problem. The interpreter executes test1
, which has a call to testall
, which is obviously already defined, so the interpreter calls that, and the rest is the same as in the previous paragraph.
So, what if you put a call to testall
or test1
in between the test1
and test2
definitions? In that case, test2
wouldn't have been defined yet, so it would not appear in the list (first version), or would raise a NameError
(second version). But as long as you don't do that, there's no problem. And there's no good reason to do so.
If you're worried about the horrible performance cost of computing testfunctions
every time you call testall
… Well, first, that's a silly worry; how many times are you going to call it? Are your functions really so fast that the time to call and filter getmembers
even shows up on the radar? But if it really is a worry, just cache the value in your favorite of the usual ways—mutable default, privat global, function attribute, …:
def testall(arg, _functions_cache=[]):
if not _functions_cache:
_functions_cache.extend([…])
How to get a list of all the classes in one .py file?
You can use inspect
:
import myModule
import inspect
print inspect.getmembers(myModule, inspect.isclass)
Related Topics
Including Non-Python Files with Setup.Py
Insert a Row to Pandas Dataframe
Numpy "Where" with Multiple Conditions
How to Access the Child Classes of an Object in Django Without Knowing the Name of the Child Class
Generating a List of Random Numbers, Summing to 1
Finding Median of List in Python
Running Selenium with Headless Chrome Webdriver
Python: JSON.Loads Returns Items Prefixing with 'U'
Most Recent Previous Business Day in Python
Converting Dict to Ordereddict
How to Obtain the Element-Wise Logical Not of a Pandas Series
Typeerror: a Bytes-Like Object Is Required, Not 'Str' in Python and CSV
Django 1.7 Throws Django.Core.Exceptions.Appregistrynotready: Models Aren't Loaded Yet
Weird Try-Except-Else-Finally Behavior with Return Statements
Datetime to String with Series in Pandas
What Does 'Valueerror: Cannot Reindex from a Duplicate Axis' Mean