[Tutor] How to use a str object, to find the class in exact name?

Japhy Bartlett japhy at pearachute.com
Tue Mar 15 16:16:53 CET 2011


I hate to jump on this one a little late, but even getattr() is kind
of ghetto (though exec/eval is worse ;).

For setting up shell scripts or CLIs, the usual route is the optparse module.

- Japhy

2011/3/15 Yaşar Arabacı <yasar11732 at gmail.com>:
> Thanks for excellent explanations. I almost got this working. I just have
> one more problem, that is:
>
> When user enter incorrect number of arguments for a method, I naturally get
> a type error. I could probably fix that with try and catch, but that is not
> very explanatory to the user. Is there a way to get expected number of
> arguments to the method so that I can generate an error report?
>
> You can find my codes as attachment. I have split them into two files. In
> order to run it, you should run cli.py like:
>
> python cli.py
>
> Thanks in advance,
>
> Yaşar Arabacı
>
> 15-03-2011 05:39, bob gailer yazmış:
>>
>> On 3/14/2011 8:49 PM, Yaşar Arabacı wrote:
>>>
>>> As I try to implement things with getattr, I am getting a really
>>> strange error. This is my file:
>>
>> Various interspersed comments:
>>>
>>> #!/usr/bin/env python
>>> # -*- encoding:utf-8 -*-
>>> class global_variables:
>>
>> It is customary to start class names with an uppercase letter
>>
>>> "Holds class attributes, so that other classes can share them"
>>> products = 0
>>> best_bundle = []
>>> class dispatcher:
>>> def GetMethod(self,class_name,method_name):
>>>
>> It is customary to start method names with a lowercase letter
>>>
>>> """This method first finds a class if desired classexists.
>>> Then, instansites it, and returns a reference to desired method of
>>> the instance it created.
>>> """
>>>
>>> from sys import modules
>>
>> It is customary to place import statements close to the top of the
>> program, not in any class or function.
>>
>>> module = modules[self.__module__]
>>> if hasattr(module,class_name):
>>
>> What are the module's attributes?
>> insert print dir(module) to see ALL the attributes.
>>
>>> print "#debug : hasattr is true"
>>> cls = getattr(module,class_name)
>>> else:
>>> print "#debug : hasattr is false"
>>> return None
>>>
>>> "if we get a valid class, lets instantie it"
>>> if cls:
>>> a=cls()
>>> else:
>>> return None
>>> return hasattr(a,method_name) and getattr(a,method_name) or None
>>>
>>> def dispatch_command(self):
>>> """Gets command from user, finds appropriate Class/method to run
>>> and then runs it. Beware of the fact that, to be able to successfully
>>> run the method, method should take exactly two arguments,
>>> arg 1: instance of class which method resides (e.g. self)
>>> arg 2: list of other needed variables
>>>
>>> list of other variables can be used to get as many variables as possible
>>> """
>>>
>>> command = raw_input(">>>")
>>> args = command.split(" ")
>>> if len(args) < 2:
>>> return None
>>> method = self.GetMethod(args[0],args[1])
>>> return method and method(args[2:]) or None
>>>
>>> class calculate(global_variables):
>>> def bundle(self,args):
>>> print "your best bundle is -->"
>>>
>>> a = dispatcher()
>>> a.dispatch_command()
>>
>> Alternative 1
>> - put all the user-callable class definitions inside a Container class
>> (or whatever name you want)
>> - then use getattr on the Container class
>> class Container:
>> class Calculate(global_variables):
>> def bundle(self,args):
>> print "your best bundle is -->"
>>
>> Alternative 2 - use the following to create a dictionary of classes in
>> which you look up the desired class by name
>> import sys, inspect
>> thisModule = sys.modules[__name__]
>> classDict = dict((name.lower(), value) for name, value in
>> inspect.getmembers(thisModule, inspect.isclass))
>> ...
>> cls = classDict[className]
>>
>> Alternative 3
>> cls = getattr(module,class_name)
>> try:
>> if issubclass(cls, global_variables)
>> a=cls()
>> except TypeError:
>> pass
>>>
>>> I wanted to see what happens when someone gives an nonexistent
>>> function. But when I put a b, it gives me error, when I put c d it
>>> doesn't. I don't have either a or c classes, but a somehow causes
>>> problems :S This is what I did:
>>>
>>> yasar at yasar-laptop:~/best_buy> ./main.py
>>> >>>a b
>>> #debug : hasattr is true
>>> Traceback (most recent call last):
>>> File "./main.py", line 57, in <module>
>>> a.dispatch_command()
>>> File "./main.py", line 44, in dispatch_command
>>> method = self.GetMethod(args[0],args[1])
>>> File "./main.py", line 25, in GetMethod
>>> a=cls()
>>> AttributeError: dispatcher instance has no __call__ method
>>
>> The error tells you what a is. Isn't it obvious now? Remember to read
>> and understand such messages.
>>
>>> yasar at yasar-laptop:~/best_buy> ./main.py
>>> >>>c d
>>> #debug : hasattr is false
>>>
>>
>>
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
>


More information about the Tutor mailing list