Solution without using CommandManager, maybe better and more maintanable when do_* commands are registered in the ActionManager instead of the respective classes. greet i.e. could still call another class
def precmd(self, line):
# Add some methods based on condition
if some_condition:
setattr(self, 'do_bye', self.bye)
setattr(self, 'do_greet', self.greet)
return line
def postcmd(self, stop, line):
# Remove some methods based on condition
if not some_condition:
delattr(self, 'do_bye')
delattr(self, 'do_greet')
return stop
def bye(self, arg):
# Do something here
pass
def greet(self, arg):
# Do something here
pass
Another Idea:
import types
import cmd
class MyCmd(cmd.Cmd):
pass
def add_do_methods(obj):
if some_condition:
def do_bye(self, arg):
# Do something here
pass
def do_greet(self, arg):
# Do something here
pass
do_methods = {'do_bye': do_bye, 'do_greet': do_greet}
new_class_dict = dict(obj.__class__.__dict__)
new_class_dict.update(do_methods)
new_class = types.new_class(obj.__class__.__name__, (obj.__class__,), {}, lambda ns: ns.update(new_class_dict))
obj.__class__ = new_class
def remove_do_methods(obj):
if not some_condition:
new_class = types.new_class(obj.__class__.__name__, (obj.__class__,), {})
new_class_dict = dict(new_class.__dict__)
for method_name in ['do_bye', 'do_greet']:
if method_name in new_class_dict:
del new_class_dict[method_name]
new_class = types.new_class(obj.__class__.__name__, (obj.__class__,), {}, lambda ns: ns.update(new_class_dict))
obj.__class__ = new_class
# Create an instance of MyCmd
my_cmd = MyCmd()
# Add the do_* methods
add_do_methods(my_cmd)
# Call the methods
my_cmd.do_bye('arg')
my_cmd.do_greet('arg')
# Remove the do_* methods
remove_do_methods(my_cmd)
In this example, the add_do_methods() function adds the do_bye() and do_greet() methods to the class of the specified object if the some_condition is true. It does this by creating a new dictionary that includes the existing class dictionary as well as the new methods, and then creating a new class that derives from the existing class with the updated dictionary. It then sets the class of the specified object to the new class.
The remove_do_methods() function does the opposite, removing the do_bye() and do_greet() methods from the class of the specified object if the some_condition is false. It does this by creating a new dictionary that includes the existing class dictionary with the methods removed, and then creating a new class that derives from the existing class with the updated dictionary. It then sets the class of the specified object to the new class.
By using dynamic class creation and setting the class of the object to the new class, you can add and remove methods from an existing class at runtime.
Solution without using CommandManager, maybe better and more maintanable when do_* commands are registered in the ActionManager instead of the respective classes. greet i.e. could still call another class
Another Idea:
In this example, the add_do_methods() function adds the do_bye() and do_greet() methods to the class of the specified object if the some_condition is true. It does this by creating a new dictionary that includes the existing class dictionary as well as the new methods, and then creating a new class that derives from the existing class with the updated dictionary. It then sets the class of the specified object to the new class.
The remove_do_methods() function does the opposite, removing the do_bye() and do_greet() methods from the class of the specified object if the some_condition is false. It does this by creating a new dictionary that includes the existing class dictionary with the methods removed, and then creating a new class that derives from the existing class with the updated dictionary. It then sets the class of the specified object to the new class.
By using dynamic class creation and setting the class of the object to the new class, you can add and remove methods from an existing class at runtime.
Originally posted by @miron in https://github.com/miron/NeonCore/issues/10#issuecomment-1436111938