Re: [Tutor] How to use a str object, to find the class in exact name?
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ı : > 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@yasar-laptop:~/best_buy> ./main.py >>> >>>a b >>> #debug : hasattr is true >>> Traceback (most recent call last): >>> File "./main.py", line 57, in >>> 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@yasar-laptop:~/best_buy> ./main.py >>> >>>c d >>> #debug : hasattr is false >>> >> >> > > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor > > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://m
Re: [Tutor] How to use a str object, to find the class in exact name?
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@yasar-laptop:~/best_buy> ./main.py >>>a b #debug : hasattr is true Traceback (most recent call last): File "./main.py", line 57, in 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@yasar-laptop:~/best_buy> ./main.py >>>c d #debug : hasattr is false """ This is supposed to an generic command line tool, to be used with any kind of module, you should import whatever module you want to use as book like; import xxx as book License Notice: This program comes with absolutely no warranty, use at your own risk, you can use, modify, redistribute, or do whatever else you want to do with it provided that: **Author of this code cannot be held responsible for any damage this code may do. Author: Yasar Arabaci """ import main as book class Dispatcher: force_subclass = "Best_buy" # Enter name of base class, or None to enable all! def getMethod(self,class_name,method_name): """This method first finds a class if desired class exists. First letter, of the class name must be uppercased! Then, instansites it, and returns a reference to desired method of the instance it created. """ if hasattr(book,class_name): if self.force_subclass: # if this option is enabled, we will only get subclasses try: if not issubclas
Re: [Tutor] How to use a str object, to find the class in exact name?
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@yasar-laptop:~/best_buy> ./main.py >>>a b #debug : hasattr is true Traceback (most recent call last): File "./main.py", line 57, in 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@yasar-laptop:~/best_buy> ./main.py >>>c d #debug : hasattr is false -- Bob Gailer 919-636-4239 Chapel Hill NC ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use a str object, to find the class in exact name?
As I try to implement things with getattr, I am getting a really strange error. This is my file: #!/usr/bin/env python # -*- encoding:utf-8 -*- class global_variables: "Holds class attributes, so that other classes can share them" products = 0 best_bundle = [] class dispatcher: def GetMethod(self,class_name,method_name): """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 module = modules[self.__module__] if hasattr(module,class_name): 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() 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@yasar-laptop:~/best_buy> ./main.py >>>a b #debug : hasattr is true Traceback (most recent call last): File "./main.py", line 57, in 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 yasar@yasar-laptop:~/best_buy> ./main.py >>>c d #debug : hasattr is false ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use a str object, to find the class in exact name?
Yaşar Arabacı wrote: And What I want to do is a small economy application. It will work this way: user add a product name, rate how much it like it over 10, and enter its price. [repeated as many times as wanted] user will enter h(is|er) budget. user will use "calcute bundle" to show much of each product s?he should buy user will repeat any step as long as s?he likes. My advice is not to mix the backend calculation engine with the frontend user interface in the same code. Keep them separate. So you should write your classes and functions to: * store products and prices * calculate best buys for a budget * etc. And then have a separate function for the user interface, which handles: * input and output to the user * converting the user's text input to numbers, products, etc. * calling the calculation functions * printing the results (The frontend and backend can be in the same file, but they should be separate functions or classes.) At the moment, your code combines calculation with user-interface, which is a poor design: class calculate: @staticmethod def bundle(): print "your best bundle is -->" You have the class responsible for calculating the bundle also responsible for displaying it to the user. It is better to separate those two functions, and have one class for calculating the bundle and returning it (not printing it!) and another function or class responsible for calling the calculate class with the user's input, and displaying the output to the user. This will let you more easily change the user-interface, without needing to change the engine. Want to put your application in a GUI, or on a website? Change the user-interface parts, not the engine. Hope this helps! -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use a str object, to find the class in exact name?
Before being able to see 3rd answer, I did something like this and it worked for me: #!/usr/bin/env python # -*- encoding:utf-8 -*- def command_dispatcher(): "Takes comman line arguments and executes regardin method" command = raw_input(">>>") args = command.split(" ") query_string = ".".join(args[0:2]) method_args = ",".join(args[2:]) try: exec query_string+"("+method_args+")" except NameError: print "You are trying to get somethin that is not exist!" class calculate: @staticmethod def bundle(): print "your best bundle is -->" command_dispatcher() But after reading 3rd answer regarding the danger of exec, I had my doubts, Now I will try to implement what second person said about getattr, and will return here with result. And What I want to do is a small economy application. It will work this way: user add a product name, rate how much it like it over 10, and enter its price. [repeated as many times as wanted] user will enter h(is|er) budget. user will use "calcute bundle" to show much of each product s?he should buy user will repeat any step as long as s?he likes. 15-03-2011 00:14, Steven D'Aprano yazmış: Yaşar Arabacı wrote: Hi I am trying to do something like this: If you are trying to write a mini-language, the ``cmd`` and ``shlex`` modules in the standard library may be useful to you. #!/usr/bin/env python def command_dispatcher(): "Takes comman line arguments and executes regardin method" command = raw_input(">>>") args = command.split(" ") args[0].args[1] The error you get tells you exactly what is wrong: AttributeError: 'str' object has no attribute 'args' When you split the line, you get a list of strings. You extract the first string using args[0], and then look up the attribute "args" on that string, and finally look up the second element of that result. But strings don't have an attribute called args. Try this instead: getattr(args[0], args[1]) When you do that, you'll run into a bunch of new and exciting errors, starting with the fact that nothing appears to happen. Try it and see. What you will eventually need to do is: * create a class instance and store it somewhere * call the method on the class instance * print its output none of which is yet done by your script. So far, all it does it try to look up a method on a class, then throw the result away without doing anything :) class calculate: def bundle(self): print __class__ command_dispatcher() calculate.bundle won't do anything except fail, because __class__ is not a local variable. It's better to have the methods return a result, rather than print, and then have the command_dispatcher responsible for printing it. That lets you chain methods to make more powerful functions. Good luck, and have fun! ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use a str object, to find the class in exact name?
Prasad, Ramit wrote: Take a look at: http://stackoverflow.com/questions/701802/how-do-i-execute-a-string-containing-python-code-in-python And then please don't do it. eval and exec should be treated as the last resort, and then only if you really know what you are doing. They are slow, and dangerous, especially if there is *any* chance that the input strings could be coming from an untrusted user. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use a str object, to find the class in exact name?
Yaşar Arabacı wrote: Hi I am trying to do something like this: If you are trying to write a mini-language, the ``cmd`` and ``shlex`` modules in the standard library may be useful to you. #!/usr/bin/env python def command_dispatcher(): "Takes comman line arguments and executes regardin method" command = raw_input(">>>") args = command.split(" ") args[0].args[1] The error you get tells you exactly what is wrong: AttributeError: 'str' object has no attribute 'args' When you split the line, you get a list of strings. You extract the first string using args[0], and then look up the attribute "args" on that string, and finally look up the second element of that result. But strings don't have an attribute called args. Try this instead: getattr(args[0], args[1]) When you do that, you'll run into a bunch of new and exciting errors, starting with the fact that nothing appears to happen. Try it and see. What you will eventually need to do is: * create a class instance and store it somewhere * call the method on the class instance * print its output none of which is yet done by your script. So far, all it does it try to look up a method on a class, then throw the result away without doing anything :) class calculate: def bundle(self): print __class__ command_dispatcher() calculate.bundle won't do anything except fail, because __class__ is not a local variable. It's better to have the methods return a result, rather than print, and then have the command_dispatcher responsible for printing it. That lets you chain methods to make more powerful functions. Good luck, and have fun! -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use a str object, to find the class in exact name?
Take a look at: http://stackoverflow.com/questions/701802/how-do-i-execute-a-string-containing-python-code-in-python Ramit Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology 712 Main Street | Houston, TX 77002 work phone: 713 - 216 - 5423 -Original Message- From: tutor-bounces+ramit.prasad=jpmchase@python.org [mailto:tutor-bounces+ramit.prasad=jpmchase@python.org] On Behalf Of Yasar Arabaci Sent: Monday, March 14, 2011 4:16 PM To: tutor@python.org Subject: [Tutor] How to use a str object, to find the class in exact name? Hi I am trying to do something like this: #!/usr/bin/env python def command_dispatcher(): "Takes comman line arguments and executes regardin method" command = raw_input(">>>") args = command.split(" ") args[0].args[1] class calculate: def bundle(self): print __class__ command_dispatcher() What I need this to do is, take a raw input, split it into parts and execute class args[0] and method args[1] using args[2:] as an argument. But what I have done isn't working. This is the error I get: :!/home/yasar/best_buy/main.py >>>calculate bundle Traceback (most recent call last): File "/home/yasar/best_buy/main.py", line 10, in command_dispatcher() File "/home/yasar/best_buy/main.py", line 6, in command_dispatcher args[0].args[1] AttributeError: 'str' object has no attribute 'args' shell returned 1 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor This communication is for informational purposes only. It is not intended as an offer or solicitation for the purchase or sale of any financial instrument or as an official confirmation of any transaction. All market prices, data and other information are not warranted as to completeness or accuracy and are subject to change without notice. Any comments or statements made herein do not necessarily reflect those of JPMorgan Chase & Co., its subsidiaries and affiliates. This transmission may contain information that is privileged, confidential, legally privileged, and/or exempt from disclosure under applicable law. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein (including any reliance thereon) is STRICTLY PROHIBITED. Although this transmission and any attachments are believed to be free of any virus or other defect that might affect any computer system into which it is received and opened, it is the responsibility of the recipient to ensure that it is virus free and no responsibility is accepted by JPMorgan Chase & Co., its subsidiaries and affiliates, as applicable, for any loss or damage arising in any way from its use. If you received this transmission in error, please immediately contact the sender and destroy the material in its entirety, whether in electronic or hard copy format. Thank you. Please refer to http://www.jpmorgan.com/pages/disclosures for disclosures relating to European legal entities. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] How to use a str object, to find the class in exact name?
Hi I am trying to do something like this: #!/usr/bin/env python def command_dispatcher(): "Takes comman line arguments and executes regardin method" command = raw_input(">>>") args = command.split(" ") args[0].args[1] class calculate: def bundle(self): print __class__ command_dispatcher() What I need this to do is, take a raw input, split it into parts and execute class args[0] and method args[1] using args[2:] as an argument. But what I have done isn't working. This is the error I get: :!/home/yasar/best_buy/main.py >>>calculate bundle Traceback (most recent call last): File "/home/yasar/best_buy/main.py", line 10, in command_dispatcher() File "/home/yasar/best_buy/main.py", line 6, in command_dispatcher args[0].args[1] AttributeError: 'str' object has no attribute 'args' shell returned 1 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor