How do you find all modules and classes within a module, recursively?
class Module
def all_the_modules
[self] + constants.map {|const| const_get(const) }
.select {|const| const.is_a? Module }
.flat_map {|const| const.all_the_modules }
end
end
A.all_the_modules
# => [A, A::Aa, A::Aa::B]
This code will break if you do have circular namespaces, akaA::Aa::B.const_set(:A, A)
.
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.
How to import recursively all classes in a module?
Solved by adding this to __init__.py
. May not be the best approach for most situations, but it is good enough for my use case.
from pathlib import Path
# Include all classes when 'from mypkg import *' is called.
fs = [f for f in Path('mypkg').rglob('*.py') if not f.name.startswith('_')]
for f in [str(f).replace('/', '.')[:-3] for f in fs]:
statement = f'from {f} import *'
exec(statement)
Find classes available in a Module
Classes are accessed through constants. Classes defined within a module are listed as constants in that module. So you just need to choose the constants that refer to classes.
MyModule.constants.select {|c| MyModule.const_get(c).is_a? Class}
Trying to find all classes that include a module
[Note: @engineersmnky illustrates a way to do this using flat_map
eliminating the need for the matching_classes
parameter. I found it more difficult to understand, but it's a perfectly sound use of flat_map
and a worthy solution. The code is posted at https://repl.it/@engineersmnky/IllinformedMountainousAnkole ]
The following code uses recursion to descend the inverted tree of modules. The result (printed at the very end) is correct, and includes classes in two modules. (I've coded a minimal module and class hierarchy to use as an example.)
#!/usr/bin/env ruby
module ParentModule
module OtherModule; end
class ParentClassYes; include OtherModule; end
class ParentClassNo; end
module ChildModule
class ChildClassYes; include OtherModule; end
class ChildClassNo; end
end
end
def classes_for_module_tree(the_module, matching_classes = [])
the_module.constants.each_with_object(matching_classes) \
do |const, matching_classes|
value = the_module.const_get(const)
if value.is_a?(Class)
if value.included_modules.include?(ParentModule::OtherModule)
matching_classes << value
end
elsif value.is_a?(Module)
# Here is where we call this method recursively. We suspend collecting
# matches for this module, call the method to process the newly found
# (sub)module, then use the array returned by that invocation to resume
# processing this module.
matching_classes = classes_for_module_tree(value, matching_classes)
end
end
matching_classes
end
p classes_for_module_tree(ParentModule)
# prints: [ParentModule::ParentClassYes, ParentModule::ChildModule::ChildClassYes]
Get all classes defined in module ruby
Here is one way
module A
class Klass
end
X = 10
module B;end
end
# Just to list the class(s) defined inside A
A.constants.select { |k| A.const_get(k).instance_of? Class } # => [:Klass]
Nice post to do the same in recursively.
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 can I discover classes in a specific package in python?
Scanning modules isn't good idea. If you need class registry you should look at metaclasses or use existing solutions like zope.interface.
Simple solution through metaclasses may look like that:
from functools import reduce
class DerivationRegistry(type):
def __init__(cls,name,bases,cls_dict):
type.__init__(cls,name,bases,cls_dict)
cls._subclasses = set()
for base in bases:
if isinstance(base,DerivationRegistry):
base._subclasses.add(cls)
def getSubclasses(cls):
return reduce( set.union,
( succ.getSubclasses() for succ in cls._subclasses if isinstance(succ,DerivationRegistry)),
cls._subclasses)
class Base(object):
__metaclass__ = DerivationRegistry
class Cls1(object):
pass
class Cls2(Base):
pass
class Cls3(Cls2,Cls1):
pass
class Cls4(Cls3):
pass
print(Base.getSubclasses())
Related Topics
Bitwise Operations on Strings with Ruby
How to Require File from 'Gem' Which Are Not Under 'Lib' Directory
How to Modify a Text File in Ruby
Parsing Date from Text Using Ruby
Best Way to Handle Category/Subcategory Relationship Ruby on Rails
Why Will a Range Not Work When Descending
Ruby Errors with Os X Yosemite
Run System Command in Ruby and Interact with It
Simple Conversion of String to Utf-8 in Ruby 1.8
Can Someone Please Explain Class << Self to Me
How to Remove Blank Values Params from Query String
Ruby: Uri::Invalidurierror (Uri Must Be Ascii Only
Nokogiri Requires Ruby Version < 2.3
Finding Common String in Array of Strings (Ruby)
Why Does Ruby Only Permit Certain Operator Overloading