0

The scenerio is I'm using an arg parser to get a command line argument auth_application.

auth_application command can have many values, for example:

cheese
eggs
noodles
pizza

These values are related to a programmable class.

I'd like a way to name the class, possible using a decorator.

So I can say

if auth_application is Cheese.__name__:
    return Cheese()

Currently I maintain a tuple of auth_application names and have to expose that to my arg parser class as well as import the classes I need.

Anyways to make this better? Is there a decorator for classes to name them?

I'm looking for a python 2.7 solution, but a python 3 solution might be useful to know.

visc
  • 4,794
  • 6
  • 32
  • 58
  • 1
    Could you use a dictionary like `classes = {'cheese':Cheese, 'eggs':Eggs}`? – TigerhawkT3 Sep 22 '15 at 03:46
  • That's basically what I have. I'm trying to reduce the steps needed/make it easier to maintain (fewer steps) – visc Sep 22 '15 at 03:50
  • I have a tuple ('cheese', 'egg' ...) and A bunch of if statements – visc Sep 22 '15 at 03:51
  • if the classes all inherit from a common class, say `Food`, you could iterate through all the descendants of that base class without hardcoding a mapping using [`__subclasses__()`](http://stackoverflow.com/questions/3862310/how-can-i-find-all-subclasses-of-a-given-class-in-python) – lemonhead Sep 22 '15 at 03:58
  • You may want to take a look at this: http://stackoverflow.com/questions/10773348/get-python-class-object-from-string – Ozgur Vatansever Sep 22 '15 at 04:01
  • 1
    @JeffreyHaines please post your code fully, we can't predict what you've done so far. – Ozgur Vatansever Sep 22 '15 at 04:08
  • What I wrote is sufficient for most – visc Sep 22 '15 at 04:56

4 Answers4

1

Easy peasy.

class command(object):
  map = {}

  def __init__(self, commandname):
    self.name = commandname

  def __call__(self, cls):
    command.map[self.name] = cls
    return cls

  class NullCommand(object):
    pass

@command('cheese')
class Cheese(object):
  pass

@command('eggs')
class Eggs(object):
  pass

def func(auth_application):
    return command.map.get(auth_application, command.NullCommand)()
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
0

Absolutely you can! You need to understand class attributes.

class NamedClass(object):
    name = "Default"

class Cheese(NamedClass):
    name = "Cheese"

print(Cheese.name)
> Cheese
Vikram Saran
  • 1,143
  • 8
  • 17
0

You can just keep a sinlge list of all of your "allowed classes" and iterate over that to find the class being referred to from the command line.

allow_classes = [Cheese,Eggs,Noodles,Pizza]

for cls in allow_classes:
    if auth_application.lower() is cls.__name__.lower():
        return cls()
0

You can use the standard Inspect Library to get the real class names, without having to augment your classes with any extra data - and this works for any class, in any module - even if you don't have the source code.

For instance - to list all the classes defined in mymodule :

import mymodule
import inspect

for name, obj in inspect.getmembers(mymodule, inspect.isclass):
    print name

the obj variable is a real class object - which you can use to declare an instance, access class methods etc.

To get the definition of a class by it's name string - you can write a simple search function :

import mymodule
import inspect

def find_class(name):
    """Find a named class in mymodule"""
    for this_name, _cls_ in inspect.getmembers(mymodule, inspect.isclass):
        if this_name = name:
            return _cls_
    return None

 ....
# Create an instance of the class named in auth_application
find_class(auth_application)(args, kwargs)

NB: Code snippets not tested

Tony Suffolk 66
  • 9,358
  • 3
  • 30
  • 33