corvid
corvid

Reputation: 11197

exposing the inner methods of a class, and using them

Let's say I have a class like so:

class Shell:
  def cat(self, file):
    try:
      with open(file, 'r') as f:
        print f.read()
     except IOError:
      raise IOError('invalid file location: {}'.format(f))
   def echo(self, message):
     print message
   def ls(self, path):
     print os.listdir(path)

In a javascript context, you might be able to do something like "Class"[method_name](), depending on how things were structured. I am looking for something similar in python to make this a "simulated operating system". EG:

import os
def runShell(user_name):
  user_input = None
  shell = Shell()
  while(user_input != 'exit' or user_input != 'quit'):
    user_input = raw_input('$'+ user_name + ': ')
    ...

now, the idea is they can type in something like this...

$crow: cat ../my_text

... and behind the scenes, we get this:

shell.cat('../my_text')

Similarly, I would like to be able to print all method definitions that exist within that class when they type help. EG:

$crow: help\n
> cat (file)
> echo (message)
> ls (path)

is such a thing achievable in python?

Upvotes: 1

Views: 71

Answers (1)

Henry Keiter
Henry Keiter

Reputation: 17188

You can use the built-in function vars to expose all the members of an object. That's maybe the simplest way to list those for your users. If you're only planning to print to stdout, you could also just call help(shell), which will print your class members along with docstrings and so on. help is really only intended for the interactive interpreter, though, so you'd likely be better off writing your own help-outputter using vars and the __doc__ attribute that's magically added to objects with docstrings. For example:

class Shell(object):
    def m(self):
        '''Docstring of C#m.'''
        return 1
    def t(self, a):
        '''Docstring of C#t'''
        return 2

for name, obj in dict(vars(Shell)).items():
    if not name.startswith('__'): #filter builtins
        print(name, '::', obj.__doc__)

To pick out and execute a particular method of your object, you can use getattr, which grabs an attribute (if it exists) from an object, by name. For example, to select and run a simple function with no arguments:

fname = raw_input()
if hasattr(shell, fname):
    func = getattr(shell, fname)
    result = func()
else:
    print('That function is not defined.')

Of course you could first tokenize the user input to pass arguments to your function as needed, like for your cat example:

user_input = raw_input().split() # tokenize
fname, *args = user_input #This use of *args syntax is not available prior to Py3
if hasattr(shell, fname):
    func = getattr(shell, fname)
    result = func(*args) #The *args syntax here is available back to at least 2.6
else:
    print('That function is not defined.')

Upvotes: 1

Related Questions