Re: Pygobject style question
On 01Aug2020 13:32, Chris Green wrote: >Having (after lots of help from here, thank you) finally converted my >Python 2, gtk 2 program to Python 3 and pygobject gtk 3 I'm left with >a couple of what might be called style questions. > >I guess it's mostly down to what feels right to me but there may be >good reasons for choosing one way over another and, if so, I'd like to >know what they are. > >So, my original code had:- >... >self.buffer = gtk.TextBuffer() >self.view = gtk.TextView(self.buffer) > >This doesn't work in gtk+ 3 (or at least I don't think it does, the >converter script changed it) and there seem to be several ways of >doing it now:- > >self.buffer = Gtk.TextBuffer() >self.view = Gtk.TextView(buffer = self.buffer) I like this first one. It is least verbose, and it makes the buffer before it makes the view, which I prefer. If they are all legal and all correct and equivalent, go with the one which is easiest to read. Cheers, Cameron Simpson -- https://mail.python.org/mailman/listinfo/python-list
Pygobject style question
Having (after lots of help from here, thank you) finally converted my Python 2, gtk 2 program to Python 3 and pygobject gtk 3 I'm left with a couple of what might be called style questions. I guess it's mostly down to what feels right to me but there may be good reasons for choosing one way over another and, if so, I'd like to know what they are. So, my original code had:- ... ... self.buffer = gtk.TextBuffer() self.view = gtk.TextView(self.buffer) ... ... This doesn't work in gtk+ 3 (or at least I don't think it does, the converter script changed it) and there seem to be several ways of doing it now:- ... ... self.buffer = Gtk.TextBuffer() self.view = Gtk.TextView(buffer = self.buffer) ... ... ... ... self.buffer = Gtk.TextBuffer() self.view = Gtk.TextView.new_with_buffer(self.buffer) ... ... ... ... self.view = Gtk.TextView() self.buffer = self.view.get_buffer() ... ... ... ... self.view = Gtk.TextView() self.buffer = Gtk.TextBuffer() self.view.set_buffer(self.buffer) ... ... Is there any reason to prefer any one of the above over the others? Obviously the last one is a line more but lends itself to using several Gtk.TextBuffer objects in on Gtk.TextView. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Package setup best practice style question
On Sun, 29 May 2016 03:00 am, Steven D'Aprano wrote: > On Sun, 29 May 2016 02:15 am, Gerald Britton wrote: > >> suppose I have a simple python project setup like this: [...] To which I responded: > If this is a single project, why do you set it up like this? Is there a > reason why you don't just have: [...] I'm sorry, on re-reading my post I realise that it might come across as a bit confrontational. Sorry Gerald, it wasn't intended that way. I was just intending to point out that we aren't forced to use a package structure at all, unless it brings actual advantages to the project. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: Package setup best practice style question
On Sun, 29 May 2016 02:15 am, Gerald Britton wrote: > suppose I have a simple python project setup like this: > > Project diectory > prog.py > pkg directory > __init__.py > mod1.py >class A: If this is a single project, why do you set it up like this? Is there a reason why you don't just have: prog.py # contains class A or even: prog.py mod1.py # contains class A Or if the project is so big it needs to be a package, make it executable: prog/ __init__.py mod1.py __main__.py This layout is now executable using: python -m prog which automatically calls __main__.py. But if you don't have a good reason for using a package, don't use a package. Use the simplest project layout that solves your problem. But for the rest of my comments, I'm going to assume that you DO have a good reason. > In order to have class A (unqualified) available from prog.py, there are a > few options that I know about. I'm currently considering two of them and > would like some feedback on best practices. > > 1. in pkg.__init__.py add: > >from pkg.mod1 import A This kinda-sorta defeats the purpose, or at least one purpose, of using a package. Which is fine, so long as you understand that's what you are doing. Generally speaking, one of the purposes of using a package layout is to allow unused sub-modules to be left unloaded unless needed. So pkg.mod1 doesn't get loaded unless you need it, in which case you explicitly call import pkg.mod1 or from pkg.mod1 import A as you prefer. By putting that import in the pkg __init__ file, you're making it automatically occur as soon as pkg is imported. Is that what you intend? If so, then it is fine, and feel free to do it. But in that case, why not just move class A into pkg/__init__.py? > in prog.py add: > >from pkg import A *shrug* This entirely depends on the purpose and use of pkg. When you give generic, meaningless names, I can only respond with wishy-washy, sit-on- the-fence generic advice. If the appropriate API is for callers to say: from pkg import A then this is the right way to design your package. But if the right API is: from pkg.mod1 import A then don't do it this way, instead do it as follows. > 2. leave __init__.py empty > in prog.py add: > > from pkg.mod1 import A > > > Is there a preference or best practice that would indicate to prefer > method > 1 or method 2? Are there methods 3, 4, 5, ... that I should consider that > are even better? One purpose of using a package is to have alternative implementations. For instance I have a package which has to support Python 2.4 where the "with" statement is not available, so I design it like this: package/ __init__.py module.py module24.py Since the user doesn't choose which implementation to use, I have this in the init file: try: from module import thing except SyntaxError: from module24 import thing and then the caller uses: from package import thing and is none the wiser. On the other hand, if the user was supposed to choose, then I would have then call: from package.redblack import Tree from package.avl import Tree from package.scapegoat import Tree and let the user choose which implementation they wanted. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Package setup best practice style question
suppose I have a simple python project setup like this: Project diectory prog.py pkg directory __init__.py mod1.py class A: In order to have class A (unqualified) available from prog.py, there are a few options that I know about. I'm currently considering two of them and would like some feedback on best practices. 1. in pkg.__init__.py add: from pkg.mod1 import A in prog.py add: from pkg import A 2. leave __init__.py empty in prog.py add: from pkg.mod1 import A Is there a preference or best practice that would indicate to prefer method 1 or method 2? Are there methods 3, 4, 5, ... that I should consider that are even better? -- Gerald Britton, MCSE-DP, MVP LinkedIn Profile: http://ca.linkedin.com/in/geraldbritton -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On 12/03/2014 12:02 PM, Chris Angelico wrote: When importing a module from a subpackage, it's sometimes convenient to refer to it throughout the code with a one-part name rather than two. I'm going to use 'os.path' for the examples, but my actual use-case is a custom package where the package name is, in the application, quite superfluous. Throughout the code, I want to refer to path.split(), path.isfile(), etc, without the os. in front of them. I could do either of these: import os.path as path from os import path Which one would you recommend? Does it depend on context? One argument not yet brought up by anyone else: if you ever wanted to make the module part of your own package and turn the import into a relative one, only the second, but not the first form lets you replace the package name with . : from . import path (while import .path is a SyntaxError, so you'd need a slightly more complicated rewrite). Wolfgang -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
- Original Message - From: Chris Angelico ros...@gmail.com To: python-list@python.org Sent: Wednesday, 3 December, 2014 12:02:17 PM Subject: Style question: Importing modules from packages - 'from' vs 'as' When importing a module from a subpackage, it's sometimes convenient to refer to it throughout the code with a one-part name rather than two. I'm going to use 'os.path' for the examples, but my actual use-case is a custom package where the package name is, in the application, quite superfluous. Throughout the code, I want to refer to path.split(), path.isfile(), etc, without the os. in front of them. I could do either of these: import os.path as path from os import path Which one would you recommend? Does it depend on context? An as import works only if it's a module in a package, where the from import can also import other objects (you can't go import pprint.pprint as pprint). I'm fairly sure that's an argument... on one side or another. :) Thoughts? ChrisA -- https://mail.python.org/mailman/listinfo/python-list I know you specifically stated you didn't want to do this but import os os.path.isfile() is the best option imo, especially from the reader point of view (Namespaces are one honking great idea). -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On 12/04/2014 09:36 AM, Jean-Michel Pichavant wrote: I know you specifically stated you didn't want to do this but import os os.path.isfile() is the best option imo, especially from the reader point of view (Namespaces are one honking great idea). But, Flat is better than nested ! ;) -- ~Ethan~ signature.asc Description: OpenPGP digital signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On 12/03/2014 03:02 AM, Chris Angelico wrote: Throughout the code, I want to refer to path.split(), path.isfile(), etc, without the os. in front of them. I could do either of these: import os.path as path from os import path Which one would you recommend? Does it depend on context? I recommend the one with less typing. ;) -- ~Ethan~ signature.asc Description: OpenPGP digital signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On Fri, Dec 5, 2014 at 4:36 AM, Jean-Michel Pichavant jeanmic...@sequans.com wrote: I know you specifically stated you didn't want to do this but import os os.path.isfile() is the best option imo, especially from the reader point of view (Namespaces are one honking great idea). With os.path it definitely is. With the actual code in question, it's a Python 2.7 project that mostly uses relative imports - inside package.module1 is import module2 etc - and I was writing an external script that calls on one of the modules. So it makes sense to reference it through the code the exact same way, as module.blah rather than package.module.blah. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On 04.12.2014 19:05, Chris Angelico wrote: With os.path it definitely is. With the actual code in question, it's a Python 2.7 project that mostly uses relative imports - inside package.module1 is import module2 etc - and I was writing an external script that calls on one of the modules. What ? I'm usually thinking Python 3 not 2 and I'm never sure which Python 2.x has backported which feature of 3, but I thought implicit relative imports like you seem to describe are not working in 2.7 ? Wolfgang -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On Fri, Dec 5, 2014 at 7:56 AM, Wolfgang Maier wolfgang.ma...@biologie.uni-freiburg.de wrote: On 04.12.2014 19:05, Chris Angelico wrote: With os.path it definitely is. With the actual code in question, it's a Python 2.7 project that mostly uses relative imports - inside package.module1 is import module2 etc - and I was writing an external script that calls on one of the modules. What ? I'm usually thinking Python 3 not 2 and I'm never sure which Python 2.x has backported which feature of 3, but I thought implicit relative imports like you seem to describe are not working in 2.7 ? Hmm, I'm not sure, but certainly it does seem to work that way. Typing import foo from inside a package will import foo.py from the package directory. I haven't dug into the details of _why_, and if ever the project shifts to Python 3 (which I would like it to), we might have to change some of the import lines, but I'd still like to be able to reference foo.bar as meaning the bar top-level object in foo.py. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On 04.12.2014 22:30, Chris Angelico wrote: On Fri, Dec 5, 2014 at 7:56 AM, Wolfgang Maier wolfgang.ma...@biologie.uni-freiburg.de wrote: On 04.12.2014 19:05, Chris Angelico wrote: With os.path it definitely is. With the actual code in question, it's a Python 2.7 project that mostly uses relative imports - inside package.module1 is import module2 etc - and I was writing an external script that calls on one of the modules. What ? I'm usually thinking Python 3 not 2 and I'm never sure which Python 2.x has backported which feature of 3, but I thought implicit relative imports like you seem to describe are not working in 2.7 ? Hmm, I'm not sure, but certainly it does seem to work that way. Typing import foo from inside a package will import foo.py from the package directory. I haven't dug into the details of _why_, and if ever the project shifts to Python 3 (which I would like it to), we might have to change some of the import lines, but I'd still like to be able to reference foo.bar as meaning the bar top-level object in foo.py. I checked what the docs say about this and it is totally confusing (at least me): https://docs.python.org/3/howto/pyporting.html#from-future-import-absolute-import says: from __future__ import absolute_import Implicit relative imports (e.g., importing spam.bacon from within spam.eggs with the statement import bacon) do not work in Python 3. This future statement moves away from that and allows the use of explicit relative imports (e.g., from . import bacon). In Python 2.5 you must use the __future__ statement to get to use explicit relative imports and prevent implicit ones. In Python 2.6 explicit relative imports are available without the statement, but you still want the __future__ statement to prevent implicit relative imports. In Python 2.7 the __future__ statement is not needed. In other words, unless you are only supporting Python 2.7 or a version earlier than Python 2.5, use this __future__ statement. which I read as there has been a stepwise transition between 2.5 and 2.7 so that 2.7 now behaves like Python 3 even without the __future__ statement. OTOH, I believe you, of course, if you're saying implicit relative imports are working just fine in 2.7, but then how to interpret the In Python 2.7 the __future__ statement is not needed. above ? Wolfgang -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On Fri, Dec 5, 2014 at 9:10 AM, Wolfgang Maier wolfgang.ma...@biologie.uni-freiburg.de wrote: which I read as there has been a stepwise transition between 2.5 and 2.7 so that 2.7 now behaves like Python 3 even without the __future__ statement. OTOH, I believe you, of course, if you're saying implicit relative imports are working just fine in 2.7, but then how to interpret the In Python 2.7 the __future__ statement is not needed. above ? Hmm. To be honest, I'm not sure. The Python 2.7 __future__ module claims that absolute_import became standard in 3.0, not 2.7, which seems to conflict with what you're seeing. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Style question: Importing modules from packages - 'from' vs 'as'
When importing a module from a subpackage, it's sometimes convenient to refer to it throughout the code with a one-part name rather than two. I'm going to use 'os.path' for the examples, but my actual use-case is a custom package where the package name is, in the application, quite superfluous. Throughout the code, I want to refer to path.split(), path.isfile(), etc, without the os. in front of them. I could do either of these: import os.path as path from os import path Which one would you recommend? Does it depend on context? An as import works only if it's a module in a package, where the from import can also import other objects (you can't go import pprint.pprint as pprint). I'm fairly sure that's an argument... on one side or another. :) Thoughts? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On 3 December 2014 at 22:02, Chris Angelico ros...@gmail.com wrote: import os.path as path from os import path Bah - deleted the list and sent directly to Chris ... time to go to bed. The advantage of the former is that if you want to use a different name, it's a smaller change. But the disadvantage of the former is that if you *don't* want to rename, it violates DRY (don't repeat yourself). The difference is so marginal that I'd leave it to personal preference, and wouldn't pull someone up for either in a code review. Tim Delaney -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
Chris Angelico wrote: When importing a module from a subpackage, it's sometimes convenient to refer to it throughout the code with a one-part name rather than two. I'm going to use 'os.path' for the examples, but my actual use-case is a custom package where the package name is, in the application, quite superfluous. Throughout the code, I want to refer to path.split(), path.isfile(), etc, without the os. in front of them. I could do either of these: import os.path as path from os import path Which one would you recommend? Does it depend on context? Don't repeat yourself, so from os import path always. On the other hand I have never thought about actual renames, e. g. from os import path as stdpath versus import os.path as stdpath I think I'd use the latter as it looks simpler. An as import works only if it's a module in a package, where the from import can also import other objects (you can't go import pprint.pprint as pprint). I'm fairly sure that's an argument... on one side or another. :) In theory you could sometimes catch erroneous assumptions about pprint.pprint's type. But I don't care. -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On Wed, Dec 3, 2014 at 10:27 PM, Peter Otten __pete...@web.de wrote: Don't repeat yourself, so from os import path always. On the other hand I have never thought about actual renames, e. g. from os import path as stdpath versus import os.path as stdpath I think I'd use the latter as it looks simpler. Thanks, Peter and Tim. Keeping DRY is worth doing (the more so as it's raining as I type this...), and I won't be renaming in this, so the from-import wins - but as Tim says, it's a close race. I do like the turn-around times on this list. Although, of course, it's entirely possible there'll be a week's worth of posts coming when someone hits on a controversial subaspect of the question somewhere; any volunteers? :) :) ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On Dec 3, 2014 4:34 AM, Chris Angelico ros...@gmail.com wrote: On Wed, Dec 3, 2014 at 10:27 PM, Peter Otten __pete...@web.de wrote: Don't repeat yourself, so from os import path always. On the other hand I have never thought about actual renames, e. g. from os import path as stdpath versus import os.path as stdpath I think I'd use the latter as it looks simpler. Thanks, Peter and Tim. Keeping DRY is worth doing (the more so as it's raining as I type this...), and I won't be renaming in this, so the from-import wins - but as Tim says, it's a close race. To offer a counterpoint, the from import is also less explicit. With import os.path as path, path must be a module. With the from import, path could be either a module or just any attribute of the os module. My preference when importing modules is to use the fully qualified name -- os.path, not path. If I do a submodule import, I'm probably assigning a local name anyway, so I still prefer the import as over the from import as. -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question: Importing modules from packages - 'from' vs 'as'
On 12/3/2014 6:02 AM, Chris Angelico wrote: When importing a module from a subpackage, it's sometimes convenient to refer to it throughout the code with a one-part name rather than two. I'm going to use 'os.path' for the examples, but my actual use-case is a custom package where the package name is, in the application, quite superfluous. Throughout the code, I want to refer to path.split(), path.isfile(), etc, without the os. in front of them. I could do either of these: import os.path as path from os import path Which one would you recommend? Does it depend on context? I confirmed that they do the same thing for submodules. import os.path as pth from os import path pth module 'ntpath' from 'C:\\Programs\\Python34\\lib\\ntpath.py' path module 'ntpath' from 'C:\\Programs\\Python34\\lib\\ntpath.py' id(pth) 4319096 id(path) 4319096 I and most code I have seen uses from tkinter import ttk. An as import works only if it's a module in a package, where the from import can also import other objects (you can't go import pprint.pprint as pprint). I'm fairly sure that's an argument... on one side or another. import tkinter.ttk as ttk makes it clear that ttk is a module rather than, say, a class. That might make things easier for the reader. On the other hand, duplication implies that there might be a real renaming, so having to compare to see that there is not, is extra work. from idlelib import EditorWindow import idlelib.EditorWindow as EditorWindow -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
On Thursday, October 30, 2014 4:10:23 AM UTC-7, Steven D'Aprano wrote: I don't particularly like either version. I prefer this: def load_int(obj): if isinstance(obj, int): # Case 1), an int, e.g. 7 return obj elif isinstance(obj, str): # Case 2) and 3), a str or JSON serialised int. # E.g. '7' or '7'. try: return int(obj) except ValueError: return int(json.loads(obj)) raise TypeError('require int or str, got %s' % type(obj).__name__) This will definitely work, but then I don't see a benefit of EAFP and duck-typing: Let's say I have a class class FakeInt(object): def __int__(self): return 42 In this case: fi = FakeInt() isinstance(fi, int) False int(fi) 42 So probably I need to rephrase 1) something, that I can cast to int. Same for elif isinstance(obj, str): As long as it behaves like string (can be some sort if bytearray). For particularly this case, it will probably won't happen, but again, it looks like an overloaded function with strongly typed argument. or a functional form: def tolerant_load_int(obj, default=None): try: return load_int(obj) except (ValueError, TypeError): return default values = [n for n in map(tolerant_load_int, l) if n is not None] # alternative to using map values = [n for n in (tolerant_load_int(obj) for obj in l) if n is not None] I like the idea of wrapping it up in a function and being able to use it in these functional forms. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
Anton wrote: Let's say I have an incoming list of values *l*. Every element of *l* can be one of the following options: 1) an integer value 2) a string in form of 'int_value', e.g. '7' 3) a string with a json serialization of an integer value, e.g. '7' 4) something else that should be ignored I need to transform this list into another list with values from options 1)-3) coerced to int. The code below should do this. I don't particularly like either version. I prefer this: def load_int(obj): if isinstance(obj, int): # Case 1), an int, e.g. 7 return obj elif isinstance(obj, str): # Case 2) and 3), a str or JSON serialised int. # E.g. '7' or '7'. try: return int(obj) except ValueError: return int(json.loads(obj)) raise TypeError('require int or str, got %s' % type(obj).__name__) load_int() covers the three cases you mention, and raises either ValueError for malformed strings (e.g. 'x') or TypeError for things which aren't ints (e.g. floats, dicts, etc.). Any other exception is probably a bug that needs to be fixed. Then, to cover case 4), ignoring everything else, you have a choice between a procedural form: values = [] for obj in l: try: values.append(load_int(obj)) except (ValueError, TypeError): pass or a functional form: def tolerant_load_int(obj, default=None): try: return load_int(obj) except (ValueError, TypeError): return default values = [n for n in map(tolerant_load_int, l) if n is not None] # alternative to using map values = [n for n in (tolerant_load_int(obj) for obj in l) if n is not None] -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
On 2014-10-30 11:10, Steven D'Aprano wrote: Anton wrote: Let's say I have an incoming list of values *l*. Every element of *l* can be one of the following options: 1) an integer value 2) a string in form of 'int_value', e.g. '7' 3) a string with a json serialization of an integer value, e.g. '7' 4) something else that should be ignored I need to transform this list into another list with values from options 1)-3) coerced to int. The code below should do this. I don't particularly like either version. I prefer this: def load_int(obj): if isinstance(obj, int): # Case 1), an int, e.g. 7 return obj elif isinstance(obj, str): # Case 2) and 3), a str or JSON serialised int. # E.g. '7' or '7'. try: return int(obj) except ValueError: return int(json.loads(obj)) raise TypeError('require int or str, got %s' % type(obj).__name__) [snip] How about: int(str(obj).strip('')) -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
MRAB wrote: On 2014-10-30 11:10, Steven D'Aprano wrote: Anton wrote: Let's say I have an incoming list of values *l*. Every element of *l* can be one of the following options: 1) an integer value 2) a string in form of 'int_value', e.g. '7' 3) a string with a json serialization of an integer value, e.g. '7' 4) something else that should be ignored I need to transform this list into another list with values from options 1)-3) coerced to int. The code below should do this. I don't particularly like either version. I prefer this: def load_int(obj): if isinstance(obj, int): # Case 1), an int, e.g. 7 return obj elif isinstance(obj, str): # Case 2) and 3), a str or JSON serialised int. # E.g. '7' or '7'. try: return int(obj) except ValueError: return int(json.loads(obj)) raise TypeError('require int or str, got %s' % type(obj).__name__) [snip] How about: int(str(obj).strip('')) Absolutely not. obj = '1\n\n\n\n' # not valid JSON load_int(obj) = raises ValueError int(str(obj).strip('')) = wrongly returns 1 -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
In article 54521c8f$0$12982$c3e8da3$54964...@news.astraweb.com, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Anton wrote: Let's say I have an incoming list of values *l*. Every element of *l* can be one of the following options: 1) an integer value 2) a string in form of 'int_value', e.g. '7' 3) a string with a json serialization of an integer value, e.g. '7' 4) something else that should be ignored I need to transform this list into another list with values from options 1)-3) coerced to int. The code below should do this. I don't particularly like either version. I prefer this: def load_int(obj): if isinstance(obj, int): # Case 1), an int, e.g. 7 return obj elif isinstance(obj, str): # Case 2) and 3), a str or JSON serialised int. # E.g. '7' or '7'. try: return int(obj) except ValueError: return int(json.loads(obj)) raise TypeError('require int or str, got %s' % type(obj).__name__) Depending on how strictly you're trying to do input validation, the int(json.loads(obj)) may not be what you want. It allows well-formed json encoding floats, for example. And, of course, since isinstance(True, int) True this code accepts booleans. Oh, but wait, that's by design :-) -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
Roy Smith wrote: In article 54521c8f$0$12982$c3e8da3$54964...@news.astraweb.com, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Anton wrote: Let's say I have an incoming list of values *l*. Every element of *l* can be one of the following options: 1) an integer value 2) a string in form of 'int_value', e.g. '7' 3) a string with a json serialization of an integer value, e.g. '7' 4) something else that should be ignored I need to transform this list into another list with values from options 1)-3) coerced to int. The code below should do this. I don't particularly like either version. I prefer this: def load_int(obj): if isinstance(obj, int): # Case 1), an int, e.g. 7 return obj elif isinstance(obj, str): # Case 2) and 3), a str or JSON serialised int. # E.g. '7' or '7'. try: return int(obj) except ValueError: return int(json.loads(obj)) raise TypeError('require int or str, got %s' % type(obj).__name__) Depending on how strictly you're trying to do input validation, the int(json.loads(obj)) may not be what you want. It allows well-formed json encoding floats, for example. Really? py int(json.loads(json.dumps(23.5))) 23 Damn! You're right. Back to Plan A: elif isinstance(obj, str): try: return int(obj) except ValueError: if obj and obj.startswith('') and obj.endswith(''): return int(obj[1:-1]) raise But of course even the int() function itself may be a little more flexible than we might want: py int('1') 1 So I guess the lessons are: * before writing code, you need to decide what the code is meant to do; * and that includes what input must be rejected, not just what input must be accepted. And, of course, since isinstance(True, int) True this code accepts booleans. Oh, but wait, that's by design :-) Naturally :-) If you wanted to avoid it, that's easy, add a clause: if isinstance(obj, bool): raise TypeError at the start of the function. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
On Fri, 31 Oct 2014 09:48:10 +1100, Steven D'Aprano wrote: MRAB wrote: How about: int(str(obj).strip('')) Absolutely not. obj = '1\n\n\n\n' # not valid JSON load_int(obj) = raises ValueError int(str(obj).strip('')) = wrongly returns 1 How about #!/usr/bin/python import re, json l = [1, -1, 0, '+2', '2', '-2', '0', '+3', '3', '-3', '0', json.dumps(-4), json.dumps(4), json.dumps(0), 'x', 'sqjklsqjk__', (5, 6), 7.7, -7.7, '8.8', '+8.8', '-8.8', '9.9', '+9.9', '-9.9'] patt1 = re.compile(r'^([-+]?\d+)$') patt2 = re.compile(r'^([-+]?\d+)$') def getTheInt(x): if isinstance(x,int): return x if isinstance(x,str): tmp = patt1.match(x) if tmp: return int(tmp.group(1)) tmp = patt2.match(x) if tmp: return int(tmp.group(1)) return None a = [] for n in l: a.append(getTheInt(n)) print a # end of code prints: [1, -1, 0, 2, 2, -2, 0, 3, 3, -3, 0, -4, 4, 0, None, None, None, None, None, None, None, None, None, None, None] I know re matching the strings may be overkill, but it may be the best way of checking that the string contains the expected character format to convert to an int. -- Denis McMahon, denismfmcma...@gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Python Style Question
Let's say I have an incoming list of values *l*. Every element of *l* can be one of the following options: 1) an integer value 2) a string in form of 'int_value', e.g. '7' 3) a string with a json serialization of an integer value, e.g. '7' 4) something else that should be ignored I need to transform this list into another list with values from options 1)-3) coerced to int. The code below should do this. Variant 1 === values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except ValueError: pass else: values.add(c_int) continue # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass else: values.add(c_int) continue === Is this code ugly? Does it follow EAFP? Am I missing something in language best practice? Or maybe below is more preferable way with a nested try...except clause? Variant 2 === values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except ValueError: # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass else: values.add(c_int) continue else: values.add(c_int) continue === Thanks, Anton. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 29/10/2014 10:45, Anton wrote: Let's say I have an incoming list of values *l*. Every element of *l* can be one of the following options: 1) an integer value 2) a string in form of 'int_value', e.g. '7' 3) a string with a json serialization of an integer value, e.g. '7' 4) something else that should be ignored I need to transform this list into another list with values from options 1)-3) coerced to int. The code below should do this. Variant 1 === values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except ValueError: pass else: values.add(c_int) continue # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass else: values.add(c_int) continue === Is this code ugly? Does it follow EAFP? Am I missing something in language best practice? Or maybe below is more preferable way with a nested try...except clause? Variant 2 === values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except ValueError: # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass else: values.add(c_int) continue else: values.add(c_int) continue === Thanks, Anton. Your first example is perfectly fine and is EAFP Personally, I prefer to avoid nesting when it's not necessary. - -- Martin Kemp (martin.k...@ingg.com) -BEGIN PGP SIGNATURE- Version: GnuPG v2 iQEcBAEBAgAGBQJUUM7zAAoJEJ0Re0UIDzSucugIALn/zY8RdpP8iaMShHoszzqf I0zl0mFHyqhNtwgQ0ZF7VGO+H+U0Dk8rhzTYOmEMzPTKNBGwll3fda9mOnrK9Xvp 9gQjII6DyQIWH7Z3dLcLr2e1j8OMNUSL6UmAYs8urNSIKZLowdV3JI4G/bLyW0KS y5Ko8dI6y5nOJ1P9XCmPTmags43UZfR8DrBUaAbzNcS8FGwmUE2KBkEhLQOvmpJi jmMc7wMOpq0jL+XbA+7pHUqoVZ7w1tUFjuy9I3h45tgPuTFAFB0gX+FpE+oVgO5o spQpVaOPEYN9ceLgHdKSxzdVIhOQLE6H/SYNHlsEW/ZNM6aR9n4yipgkOmtJ0+M= =WzHA -END PGP SIGNATURE- -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
Hi, first in Python 2.7.6 and Python 3.4.0 list haven't got any add function but they have append. I think you could do better with something like == import json l = [1, -1, 0, '1', '-1', '0', json.dumps(-1), json.dumps(1), json.dumps(0), 'x', 'sqjklsqjk__', (1, 2)] values = [] for c in l: try: c_int = int(c) except ValueError: pass except TypeError: pass else: values.append(c_int) continue print(values) == The code has been tested in Python 2.7.6 and 3.4 and returns [1, -1, 0, 1, -1, 0, -1, 1, 0] You don't need to do two try because you can process both exceptions in the same way. You don't really need to do json.loads because if you have a json string which is an integer, you could do that directly with int(c) which can take a string and transform in an integer. With ValueError it captures the exception when it tries to transform the characters' strings and with TypeError it captures the exception when it tries to work with the tuples. Have a good day and hope it works for you! 2014-10-29 11:42 GMT+01:00 Anton anton.schattenf...@gmail.com: Let's say I have an incoming list of values *l*. Every element of *l* can be one of the following options: 1) an integer value 2) a string in form of 'int_value', e.g. '7' 3) a string with a json serialization of an integer value, e.g. '7' 4) something else that should be ignored I need to transform this list into another list with values from options 1)-3) coerced to int. The code below should do this. Variant 1 === values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except ValueError: pass else: values.add(c_int) continue # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass else: values.add(c_int) continue === Is this code ugly? Does it follow EAFP? Am I missing something in language best practice? Or maybe below is more preferable way with a nested try...except clause? Variant 2 === values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except ValueError: # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass else: values.add(c_int) continue else: values.add(c_int) continue === Thanks, Anton. -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
2014-10-29 12:25 GMT+01:00 Martin Kemp martin.k...@ingg.com: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 29/10/2014 10:45, Anton wrote: Let's say I have an incoming list of values *l*. Every element of *l* can be one of the following options: 1) an integer value 2) a string in form of 'int_value', e.g. '7' 3) a string with a json serialization of an integer value, e.g. '7' 4) something else that should be ignored I need to transform this list into another list with values from options 1)-3) coerced to int. The code below should do this. Variant 1 === values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except ValueError: pass else: values.add(c_int) continue # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass else: values.add(c_int) continue === Is this code ugly? Does it follow EAFP? Am I missing something in language best practice? Or maybe below is more preferable way with a nested try...except clause? Variant 2 === values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except ValueError: # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass else: values.add(c_int) continue else: values.add(c_int) continue === Thanks, Anton. Your first example is perfectly fine and is EAFP Actually it doesn't work because there is no add function and it doesn't catch the TypeError function to ignore other exceptions than ValueError. Doesn't it? I tested in Python 2.7.6 and 3.4. Personally, I prefer to avoid nesting when it's not necessary. - -- Martin Kemp (martin.k...@ingg.com) -BEGIN PGP SIGNATURE- Version: GnuPG v2 iQEcBAEBAgAGBQJUUM7zAAoJEJ0Re0UIDzSucugIALn/zY8RdpP8iaMShHoszzqf I0zl0mFHyqhNtwgQ0ZF7VGO+H+U0Dk8rhzTYOmEMzPTKNBGwll3fda9mOnrK9Xvp 9gQjII6DyQIWH7Z3dLcLr2e1j8OMNUSL6UmAYs8urNSIKZLowdV3JI4G/bLyW0KS y5Ko8dI6y5nOJ1P9XCmPTmags43UZfR8DrBUaAbzNcS8FGwmUE2KBkEhLQOvmpJi jmMc7wMOpq0jL+XbA+7pHUqoVZ7w1tUFjuy9I3h45tgPuTFAFB0gX+FpE+oVgO5o spQpVaOPEYN9ceLgHdKSxzdVIhOQLE6H/SYNHlsEW/ZNM6aR9n4yipgkOmtJ0+M= =WzHA -END PGP SIGNATURE- -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 29/10/2014 12:01, Rafael Romero Carmona wrote: 2014-10-29 12:25 GMT+01:00 Martin Kemp martin.k...@ingg.com: On 29/10/2014 10:45, Anton wrote: Let's say I have an incoming list of values *l*. Every element of *l* can be one of the following options: 1) an integer value 2) a string in form of 'int_value', e.g. '7' 3) a string with a json serialization of an integer value, e.g. '7' 4) something else that should be ignored I need to transform this list into another list with values from options 1)-3) coerced to int. The code below should do this. Variant 1 === values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except ValueError: pass else: values.add(c_int) continue # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass else: values.add(c_int) continue === Is this code ugly? Does it follow EAFP? Am I missing something in language best practice? Or maybe below is more preferable way with a nested try...except clause? Variant 2 === values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except ValueError: # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass else: values.add(c_int) continue else: values.add(c_int) continue === Thanks, Anton. Your first example is perfectly fine and is EAFP Actually it doesn't work because there is no add function and it doesn't catch the TypeError function to ignore other exceptions than ValueError. Doesn't it? I tested in Python 2.7.6 and 3.4. Personally, I prefer to avoid nesting when it's not necessary. -- https://mail.python.org/mailman/listinfo/python-list Ah ok, style-wise it was fine. - -- Martin Kemp (martin.k...@ingg.com) -BEGIN PGP SIGNATURE- Version: GnuPG v2 iQEcBAEBAgAGBQJUUOD+AAoJEJ0Re0UIDzSu1KQIAK6aCMOv4VqOjmm/zoQrmzLf UGBCLwtHrnDkbXFAIweTSFiM1uf9TDaRpJqY1IrPbJHI4/EAP0Hu07nyx3V6HgzM /+Wb3DkpjW+JQoVqDSGzE/dTPJcU3/b1/EWWpbu72JHplqz9laEAFt9muWyDPs9u kDgM06mDd50lsi83W3i0H1iGL6YbLtsik+/x4G4mMjdq1o9BvRpUjkIiOx7yJ/BR OYzdudltXGqlXcToufHTU2lUv2C0RoHHNO4kytiLoUekCBdGE+Jy/6gQq/AKQu4G 0RYjCOnKNgugfdmDuHi0julPtTEzc+MdY/CcPob4cyy8RDzfQGklGKHP7f9+SJs= =hjWU -END PGP SIGNATURE- -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
On Wednesday, October 29, 2014 4:43:33 AM UTC-7, Rafael Romero Carmona wrote: Hi, first in Python 2.7.6 and Python 3.4.0 list haven't got any add function but they have append. You are right, in my original code I use set instead of array, so it should be either values = set() or values.append() in the original code. I think you could do better with something like == import json l = [1, -1, 0, '1', '-1', '0', json.dumps(-1), json.dumps(1), json.dumps(0), 'x', 'sqjklsqjk__', (1, 2)] It should also work with cases like [1, json.dumps('-1')], which is case 3), sorry if it was not clear in the initial post. values = [] for c in l: try: c_int = int(c) except ValueError: pass except TypeError: pass else: values.append(c_int) continue print(values) == The code has been tested in Python 2.7.6 and 3.4 and returns [1, -1, 0, 1, -1, 0, -1, 1, 0] You don't need to do two try because you can process both exceptions in the same way. You don't really need to do json.loads because if you have a json string which is an integer, you could do that directly with int(c) which can take a string and transform in an integer. In case of 3) an element can be a string like '1', which will fail int(...), in this case it tries to parse it with json. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Style Question
On Wednesday, October 29, 2014 4:59:25 AM UTC-7, Rafael Romero Carmona wrote: 2014-10-29 12:25 GMT+01:00 Martin Kemp mar...@ingg.com: Actually it doesn't work because there is no add function and it doesn't catch the TypeError function to ignore other exceptions than ValueError. Doesn't it? I tested in Python 2.7.6 and 3.4. Originally I was using set instead of list. So it should have been either values = set() or values.append(), but it is not relevant to the question. Regarding TypeError, I don't catch it on purpose, because I want this type of Exception to bubble up and surface as an error and be logged, because this should never be the case. I expect an element to be either something coercible to int or a string. If for some reason it is an object, then there is something wrong one layer up, so I want it to fail explicitly. -- https://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
Am 09.05.2013 02:38 schrieb Colin J. Williams: On 08/05/2013 4:20 PM, Roy Smith wrote: A list of FooEntry's +1 Go back to school. Both of you... That is NOT the way to build a plural form... Thomas -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
On 2013-05-08, Denis McMahon denismfmcma...@gmail.com wrote: On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote: FooEntry is a class. How would you describe a list of these in a docstring? A list of FooEntries A list of FooEntrys A list of FooEntry's A list of FooEntry instances The first one certainly sounds the best, but it seems wierd to change the spelling of the class name to make it plural. I wouldn't use an apostrophe for pluralisation. If there's no chance for confusion between a class named FooEntry and another named FooEntries, then the first attempt seems best. Pluralize a class name by following the usual rules, e.g., strings and ints. -- Neil Cerutti -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
Neil Cerutti writes: If there's no chance for confusion between a class named FooEntry and another named FooEntries, then the first attempt seems best. Pluralize a class name by following the usual rules, e.g., strings and ints. Like strings would be foo entries. Which might work well. (I mean, isn't the class named str?) -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
On 2013-05-09, Jussi Piitulainen jpiit...@ling.helsinki.fi wrote: Neil Cerutti writes: If there's no chance for confusion between a class named FooEntry and another named FooEntries, then the first attempt seems best. Pluralize a class name by following the usual rules, e.g., strings and ints. Like strings would be foo entries. Which might work well. (I mean, isn't the class named str?) Yeah, that's not such a good Python example. I used it to replace chars and felt good at the time. ;) -- Neil Cerutti -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
On 2013-05-08 21:20, Roy Smith wrote: FooEntry is a class. How would you describe a list of these in a docstring? A list of FooEntries A list of FooEntrys A list of FooEntry's A list of FooEntry instances The first one certainly sounds the best, but it seems wierd to change the spelling of the class name to make it plural. I'm using services like Github more and more to talk about code, so I have taken to adopting its inline markup for `code` when referring to identifiers. Thus, I will often write A list of `FooEntry`s But I don't mind A list of FooEntries Hopefully there isn't also a `FooEntries` class. -- Robert Kern I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth. -- Umberto Eco -- http://mail.python.org/mailman/listinfo/python-list
Style question -- plural of class name?
FooEntry is a class. How would you describe a list of these in a docstring? A list of FooEntries A list of FooEntrys A list of FooEntry's A list of FooEntry instances The first one certainly sounds the best, but it seems wierd to change the spelling of the class name to make it plural. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
This one: A list of FooEntry instances Besides the obvious spelling issues in the others, it's not immediately clear if the list contains just FooEntry instances, FooEntry classes (perhaps subclasses) or a mix of the two. #4 makes it clear. Skip -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
On Wed, May 8, 2013 at 4:20 PM, Roy Smith r...@panix.com wrote: FooEntry is a class. How would you describe a list of these in a docstring? A list of FooEntries A list of FooEntrys A list of FooEntry's A list of FooEntry instances The first one certainly sounds the best, but it seems wierd to change the spelling of the class name to make it plural. -- http://mail.python.org/mailman/listinfo/python-list How about: A list with elements of type FooEntry? I also like the last one: A list of FooEntry instances. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
On Wed, May 8, 2013 at 2:37 PM, John Downs john.a.do...@gmail.com wrote: On Wed, May 8, 2013 at 4:20 PM, Roy Smith r...@panix.com wrote: FooEntry is a class. How would you describe a list of these in a docstring? A list of FooEntries A list of FooEntrys A list of FooEntry's A list of FooEntry instances The first one certainly sounds the best, but it seems wierd to change the spelling of the class name to make it plural. -- http://mail.python.org/mailman/listinfo/python-list How about: A list with elements of type FooEntry? I also like the last one: A list of FooEntry instances. listFooEntry *ducks* -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote: FooEntry is a class. How would you describe a list of these in a docstring? A list of FooEntries A list of FooEntrys A list of FooEntry's A list of FooEntry instances The first one certainly sounds the best, but it seems wierd to change the spelling of the class name to make it plural. I wouldn't use an apostrophe for pluralisation. The Normal pluralisation of FooEntry would be FooEntries. Who are you expecting to read the docstring? English majors, grammar nazis, wikipedia editors, programmers, or all 4? -- Denis McMahon, denismfmcma...@gmail.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote: FooEntry is a class. How would you describe a list of these in a docstring? Which language are you writing your docstrings in? Obey the normal rules of spelling, grammar and punctuation for your language, which I assume is English. A list of FooEntries Perfectly acceptable. A list of FooEntrys There is no standard variant or dialect of English (British English, American English, etc.) that pluralises Entry as Entrys, so that would be absolutely not. A list of FooEntry's Here come's an S! Quick, jam on an apostrophe! This is called the grocer's apostrophe, and is universally held in contempt no matter what variant of English you write in. Don't do this. The only acceptable use of an apostrophe to make a plural is if the thing being pluralised is a single letter. E.g. one a, two a's. A list of FooEntry instances This is also acceptable, although a little wordy. Do you write a list of strings or a list of str instances? The first one certainly sounds the best, but it seems wierd to change the spelling of the class name to make it plural. No weirder (note spelling) than changing any other noun. Whether you change int to ints or FooEntry to FooEntries, you're still changing it. That's how you make it plural. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
On Thu, May 9, 2013 at 6:20 AM, Roy Smith r...@panix.com wrote: A list of FooEntry's Only if you put another apostrophe in: A list of 'FooEntry's But the delimited style is almost never of use. I'd go for this only if there were some sort of automated markup being applied - if the word FooEntry were turned into a hyperlink or something. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
On Wed, 08 May 2013 15:33:07 -0500, Skip Montanaro wrote: This one: A list of FooEntry instances Besides the obvious spelling issues in the others, it's not immediately clear if the list contains just FooEntry instances, FooEntry classes (perhaps subclasses) or a mix of the two. #4 makes it clear. I don't think this is a real issue. There isn't normally any ambiguity between instances and subclasses. When you read a list of ints, do you assume that the list looks like [int, MyInt, AnotherInt, FooInt] or do you expect it to look like [2, 7, 6, 1]? The normal interpretation of one or more Foo is that we're talking about Foo *instances*, not subclasses of Foo. If that is not that case, then the onus is on the author of the documentation to make it clear that they are talking about subclasses. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
On 08/05/2013 4:20 PM, Roy Smith wrote: FooEntry is a class. How would you describe a list of these in a docstring? A list of FooEntries 0 A list of FooEntrys -1 A list of FooEntry's +1 A list of FooEntry instances No FooEntry is specified as a class. The first one certainly sounds the best, but it seems wierd to change the spelling of the class name to make it plural. Colin W. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question -- plural of class name?
On 09May2013 00:02, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: | On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote: | A list of FooEntry's | | Here come's an S! Quick, jam on an apostrophe! | | This is called the grocer's apostrophe, and is universally held in | contempt no matter what variant of English you write in. Don't do this. | | The only acceptable use of an apostrophe to make a plural is if the thing | being pluralised is a single letter. E.g. one a, two a's. Frankly, not even then for me. I spell that one A, two As. | A list of FooEntry instances | | This is also acceptable, although a little wordy. Do you write a list of | strings or a list of str instances? How about a FooEntry list? -- Cameron Simpson c...@zip.com.au Yes Officer, yes Officer, I will Officer. Thank you. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: metaclass self vs cls?
The standard is to use `cls`. In the __new__ method you can use `mcl` or `meta`. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: metaclass self vs cls?
On Tue, Jul 17, 2012 at 6:23 AM, Michele Simionato michele.simion...@gmail.com wrote: The standard is to use `cls`. In the __new__ method you can use `mcl` or `meta`. I've also seen `mcs` a fair amount. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: metaclass self vs cls?
On Tue, Jul 17, 2012 at 12:10 AM, alex23 wuwe...@gmail.com wrote: On Jul 17, 1:29 am, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: Here's a style question for you: in a metaclass, what should I call the instance parameter of methods, cls or self? Maybe portmanteu it as clasself? :) What is this, 1st edition DD? Elf is a race, not a class. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: metaclass self vs cls?
On Tue, 17 Jul 2012 05:23:22 -0700, Michele Simionato wrote: The standard is to use `cls`. In the __new__ method you can use `mcl` or `meta`. Thanks to everyone who answered. I think I will stick with meta and cls. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Style question: metaclass self vs cls?
Here's a style question for you: in a metaclass, what should I call the instance parameter of methods, cls or self? class ExampleMeta(type): def method(self, *args): ... I'm not quite sure if that feels right. On the one hand, self is the ExampleMeta instance alright... but on the other, self is actually a class, so I feel I want to call it cls rather than self, which makes it more obvious that you're looking at a metaclass. On the third-hand, it may be confusing that the argument is called cls but not decorated with classdecorator. I'm very slightly leaning towards writing metaclasses like this: class ExampleMeta(type): def __new__(meta, *args): ... def method(cls, *args): ... class Example(metaclass=ExampleMeta): def another_method(self): ... What do others do? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: metaclass self vs cls?
On 7/16/2012 11:29 AM, Steven D'Aprano wrote: Here's a style question for you: in a metaclass, what should I call the instance parameter of methods, cls or self? class ExampleMeta(type): def method(self, *args): ... I'm not quite sure if that feels right. On the one hand, self is the ExampleMeta instance alright... but on the other, self is actually a class, so I feel I want to call it cls rather than self, which makes it more obvious that you're looking at a metaclass. I have never seriously written a metaclass, but as a reader I would prefer 'cls'. On the third-hand, it may be confusing that the argument is called cls but not decorated with classdecorator. To me, that reinforces 'looking as a metaclass'. An @classmethod in a class is a class method specific to the particular class. A method in a metaclass is a method common to all classes of the metaclass. They could be written differently, yet calling the first param 'cls' either way seems reasonable. I'm very slightly leaning towards writing metaclasses like this: class ExampleMeta(type): def __new__(meta, *args): ... def method(cls, *args): ... class Example(metaclass=ExampleMeta): def another_method(self): ... What do others do? Not too many people write real metaclasses. Python lets you chose. Have you looked at the C code of type? (Not that you are bound by it.) -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question (Poll)
On Wednesday, 14 March 2012 21:16:05 UTC, Terry Reedy wrote: On 3/14/2012 4:49 PM, Arnaud Delobelle wrote: On 14 March 2012 20:37, Croephacroe...@gmail.com wrote: Which is preferred: for value in list: if not value is another_value: value.do_something() break Do you really mean 'is' or '=='? If you mean x is not y, write it that way. 'not x is y' can be misread and misunderstood, depending on whether the 'is' is true or not. not 1 is 1 False not (1 is 1) False (not 1) is 1 False Does not matter how read. not (1 is 0) True (not 1) is 0 False not 1 is 0 True Does matter how read. if list and not list[0] is another_value: list[0].do_something() Or try: value = mylist[0] if value is not another_value: value.dosomething except IndexError: pass I would not do this in this case of index 0, but if the index were a complicated expression or expensive function call, making 'if list' an inadequate test, I might. Hard to say, since they don't do the same thing :) I suspect you meant: for value in list: if not value is another_value: value.do_something() break I always feel uncomfortable with this because it's misleading: a loop that never loops. I agree. Please do not do this in public ;-). -- Terry Jan Reedy I'm not sure it's efficient or even if I like it, but it avoids try/except and the use of a for loop. if next( iter(mylist), object() ) is not another_value: # ... Just my 2p, Jon. -- http://mail.python.org/mailman/listinfo/python-list
Style question (Poll)
Which is preferred: for value in list: if not value is another_value: value.do_something() break --or-- if list and not list[0] is another_value: list[0].do_something() Comments are welcome, Thanks -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question (Poll)
On 14 March 2012 20:37, Croepha croe...@gmail.com wrote: Which is preferred: for value in list: if not value is another_value: value.do_something() break --or-- if list and not list[0] is another_value: list[0].do_something() Hard to say, since they don't do the same thing :) I suspect you meant: for value in list: if not value is another_value: value.do_something() break I always feel uncomfortable with this because it's misleading: a loop that never loops. -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question (Poll)
On 3/14/2012 4:49 PM, Arnaud Delobelle wrote: On 14 March 2012 20:37, Croephacroe...@gmail.com wrote: Which is preferred: for value in list: if not value is another_value: value.do_something() break Do you really mean 'is' or '=='? If you mean x is not y, write it that way. 'not x is y' can be misread and misunderstood, depending on whether the 'is' is true or not. not 1 is 1 False not (1 is 1) False (not 1) is 1 False Does not matter how read. not (1 is 0) True (not 1) is 0 False not 1 is 0 True Does matter how read. if list and not list[0] is another_value: list[0].do_something() Or try: value = mylist[0] if value is not another_value: value.dosomething except IndexError: pass I would not do this in this case of index 0, but if the index were a complicated expression or expensive function call, making 'if list' an inadequate test, I might. Hard to say, since they don't do the same thing :) I suspect you meant: for value in list: if not value is another_value: value.do_something() break I always feel uncomfortable with this because it's misleading: a loop that never loops. I agree. Please do not do this in public ;-). -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
RE: Style question (Poll)
Which is preferred: for value in list: if not value is another_value: value.do_something() break Do you really mean 'is' or '=='? Let me expound on how 'is' and '==' are very different. It may work for some comparisons but often not for others. Certain examples work because of the Python implementation. c = 1 d = 1 c is d # This only works because CPython caches small values. True c == d True a = 10 b = 10 a is b False a == b True 10 is 10 True '10 is 10' works because the interpreter caches the number because it is on the same line. Only use 'is' if you are looking for objects like True, False, None or something that MUST be exactly the same object. In general, use '=='. Ramit Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology 712 Main Street | Houston, TX 77002 work phone: 713 - 216 - 5423 -- This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question (Poll)
On 14 March 2012 22:15, Prasad, Ramit ramit.pra...@jpmorgan.com wrote: Only use 'is' if you are looking for objects like True, False, None or something that MUST be exactly the same object. I've rarely seen valid uses of 'is True' or 'is False'. -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
RE: Style question (Poll)
Only use 'is' if you are looking for objects like True, False, None or something that MUST be exactly the same object. I've rarely seen valid uses of 'is True' or 'is False'. It can be useful when you think something might be None or False. Although, I suppose you could always just use 'is None' instead. 1 == True True 1 is True False 0 == False True 0 is False False Granted, the above example is a pretty facetious case; not sure I can come up with a reasonably real world use case. Ramit Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology 712 Main Street | Houston, TX 77002 work phone: 713 - 216 - 5423 -- This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question (Poll)
On Thu, Mar 15, 2012 at 7:37 AM, Croepha croe...@gmail.com wrote: Which is preferred: for value in list: if not value is another_value: value.do_something() break --or-- if list and not list[0] is another_value: list[0].do_something() Comments are welcome, Thanks General principle: Make the code look like what it's doing. I don't mean text art and making code in the shape of pi that prints the digits of pi (although that can be awesome too), but more that a loop should not be used when you don't intend for it to loop. Consider the For-Case Paradigm[1] and the amazing confusion value that it can offer. A loop needn't execute more than once (it needn't even execute the first time), but it should at least have the _potential_ to execute the same code multiple times, otherwise it's hardly a loop. I had a particularly nasty example of a loop-that-wasn't-a-loop at work a while ago; it was PHP, not Python, so I won't share it here, but it had a do-while loop and an insidious bug in it. Very tricky. ChrisA [1] http://thedailywtf.com/Articles/The_FOR-CASE_paradigm.aspx -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
Gerald Britton wrote: however, considering what import a.module.that.is.quite.nested as myModule Won't work since I get the objects at run time myModule = __import__('whatever.module.imported.at.run.time', globals(), locals(), [], -1) See http://docs.python.org/library/functions.html#__import__ JM -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
Gerald Britton wrote: Nope. it's nothing to do with imports. It's about objects passed to methods at run time. Complicated objects with many levels. Not about modules at all. Who is providing these objects ? - Your code ? = as said before, you can fix your design with a proper object model - 3rd party libraries ? = I'd be curious to know which one, because they usually do a good job providing a clean minimal public interface. However, do not redesign anything to get only shorter names. You can easily live with that, the way you're doing it is up to you and suggestions have been given. But keep in mind that you should'nt have got nested names that long in the first pace, no matter how complicated the internal implementation. JM -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
Gerald Britton wrote: Hi all, Today I was thinking about a problem I often encounter. [snip] 1. You need to call this thing many times with different arguments, so you wind up with: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1) y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2) z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3) [snip] -- Gerald Britton This is not solved by style but by design. You simply don't use too much nested objects. That's a sign of something wrong in your overall object model. Since I do not encounter this problem as often as you are, I guess it is a matter of habbits. however, considering what import a.module.that.is.quite.nested as myModule is doing, I guess using a local variable to store your nested method is just fine. JM -- http://mail.python.org/mailman/listinfo/python-list
Style question: Nicknames for deeply nested objects
Hi all, Today I was thinking about a problem I often encounter. Say that I have (seems I often do!) a deeply nested object, by which I mean object within object with object, etc. For example: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value) Well, that's extreme but I've worked with code approaching that level of nested-ness. Now, consider two scenarios: 1. You need to call this thing many times with different arguments, so you wind up with: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1) y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2) z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3) 2. You call it inside a loop: for item in some_iterable: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value) For one thing, I find the long lines unattractive at best and error-prone at worst, especially if I also have some.other.deeply.nested.object.method that I might confuse with the first. To make it look better I might do this: _o = some.deeply.nested.object _o.method(_o.value) which is fine, I suppose. Then, putting on my company hat, I remembered that, from VBA, you could do this: with some.deeply.nested.object .method(.value) end with I like the structure of this, since the subordinate block can be indented, which makes it stand out. Also, it avoids temporary variables. So, I was thinking of how to get close to this in Python. I came up with two approaches: 1. _o = some.deeply.nested.object if 1: _o.method(_o.value) The if 1: forces me to indent the subordinate code, which sets it apart from the surrounding code. Note that I cannot just indent because I feel like it since Python is persnickety about indentation. 2. for _o in [some.deeply.nested.object]: _o.method(_o.value) The for... sets up the iterator and forces me to indent the subordinate code. As an aside, approach 1 generates less byte-code since approach 2 sets up loop machinery which you don't really need in this case. I have a couple of questions: 1. If you had to choose between approaches 1 and 2, which one would you go for, and why? 2. What other techniques have you used in such a situation? -- Gerald Britton -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On Jan 30, 11:51 am, Gerald Britton gerald.brit...@gmail.com wrote: [...] that I might confuse with the first. To make it look better I might do this: _o = some.deeply.nested.object _o.method(_o.value) which is fine, I suppose. It is very fine. And you supposed correctly! Then, putting on my company hat, I remembered that, from VBA, you could do this: with some.deeply.nested.object .method(.value) end with I like the structure of this, since the subordinate block can be indented, which makes it stand out. Also, it avoids temporary variables. Yes it is a good idea! Well forgetting the horrendous VBA syntax this is. I brought this up many moons back as a feature request: Local Blocks. Here is how a pythonic local block would look with this as localvar: localvar.do_something() So, I was thinking of how to get close to this in Python. I came up with two approaches: 1. _o = some.deeply.nested.object if 1: _o.method(_o.value) bad idea! 2. for _o in [some.deeply.nested.object]: _o.method(_o.value) even worse idea! I have a couple of questions: 1. If you had to choose between approaches 1 and 2, which one would you go for, and why? neither! Stick with the original. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
In article mailman.1469.1296409883.6505.python-l...@python.org, Gerald Britton gerald.brit...@gmail.com wrote: 1. You need to call this thing many times with different arguments, so you wind up with: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1) y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2) z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3) I would probably turn that into: object = some.deeply.nested.object object.method(object.value1) object.method(object.value2) object.method(object.value3) i.e. make the temporary variable have the exact same name as the last component of the deeply nested thing you're trying to refactor. If the scope of use is small and the meaning is obvious from context, sometimes I'll shorten the name, i.e. obj = some.deeply.nested.object or even o = some.deeply.nested.object but I tend to avoid doing that. I'd rather be a little more verbose in preference to being a little more cryptic. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On 1/30/11 9:51 AM, Gerald Britton wrote: 1. If you had to choose between approaches 1 and 2, which one would you go for, and why? Neither. Ideally, I'd tweak the API around so the deeply nested structure isn't something I need to access regularly. But! If you can't do that, I'd do something like: --- start from contextlib import contextmanager class Item(object): pass deeply = Item() deeply.nested = Item() deeply.nested.thing = Item() @contextmanager def my(thing): yield thing with my(deeply.nested.thing) as o: o.hello = 1 print deeply.nested.thing.hello --- end That's a dummy context-manager which basically does nothing: it just abuses the context manager protocol to basically make a local variable and indent its usage. Its really just a run-around and slightly less efficient to do: _o = some.deeply.nested.object _o.method(_o.value) But with the whitespace added on. Personally, I'd usually just make a local variable and skip any tricks. -- Stephen Hansen ... Also: Ixokai ... Mail: me+list/python (AT) ixokai (DOT) io ... Blog: http://meh.ixokai.io/ signature.asc Description: OpenPGP digital signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On Jan 30, 12:23 pm, Stephen Hansen me+list/pyt...@ixokai.io wrote: --- start from contextlib import contextmanager class Item(object): pass deeply = Item() deeply.nested = Item() deeply.nested.thing = Item() @contextmanager def my(thing): yield thing with my(deeply.nested.thing) as o: o.hello = 1 print deeply.nested.thing.hello --- end Well congratulations Stephen, you win the obfuscation prize of the year! -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On 1/30/11 10:35 AM, rantingrick wrote: Well congratulations Stephen, you win the obfuscation prize of the year! Yes, On 1/30/11 10:09 AM, rantingrick wrote: Here is how a pythonic local block would look with this as localvar: localvar.do_something() verses with my(this) as localvar: localvar.do_something() Is dreadfully more, er, obfuscated. I mean someone would have to know what the 'my' function does to understand what's going on! OH MY GOD. How can someone be expected to understand what a function does! Be serious! You can't expect that of them. -- Stephen Hansen ... Also: Ixokai ... Mail: me+list/python (AT) ixokai (DOT) io ... Blog: http://meh.ixokai.io/ signature.asc Description: OpenPGP digital signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On 30/01/2011 17:51, Gerald Britton wrote: Hi all, Today I was thinking about a problem I often encounter. Say that I have (seems I often do!) a deeply nested object, by which I mean object within object with object, etc. For example: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value) Well, that's extreme but I've worked with code approaching that level of nested-ness. Now, consider two scenarios: 1. You need to call this thing many times with different arguments, so you wind up with: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1) y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2) z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3) Neither. You should tell. Don't ask if you can avoid it. Compare... queen.getButter() and queen.dairymaid.alderney.getButter() see http://www.timelessteacherstuff.com/readerstheater/KingsBreakfast.pdf king doesn't care where or how the butter is brought. Neither should your code! What are you doing with value1, value2 and value3 when you have them anyway? Stuffing them 3 levels deep into something else? Stop writing procedural code, and write object oriented code instead! If you you make some tell deeply.nested.object about other.deeply.nested.object it can fetch its own values, but it might be better to have some tell other.deeply.nested.object about deeply.nested.object to it can issue the correct commands. Then you tell some to do Somthing by writing some.takeMeaningfullAction() and it all happens under the covers. Regards Ian -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On Jan 30, 12:53 pm, Stephen Hansen me+list/pyt...@ixokai.io wrote: On 1/30/11 10:35 AM, rantingrick wrote: Well congratulations Stephen, you win the obfuscation prize of the year! Yes, On 1/30/11 10:09 AM, rantingrick wrote: Here is how a pythonic local block would look with this as localvar: localvar.do_something() verses with my(this) as localvar: localvar.do_something() Is dreadfully more, er, obfuscated. Absolutely! I mean someone would have to know what the 'my' function does to understand what's going on! Yes, and also how decorators word and generators work, and ... OH MY GOD. How can someone be expected to understand what a function does! Yes, and also how decorators word and generators work, and ... Be serious! You can't expect that of them. I don't. I don't expect anyone to write 10 lines of obfuscation code when just two will suffice. Maybe you should join the perl group as they would proud! -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
I don't. I don't expect anyone to write 10 lines of obfuscation code when just two will suffice. Maybe you should join the perl group as they would proud! But Stephen's 10 lines of somewhat obscure code actually works, and your two lines of code doesn't. I know which one I would prefer. -- Jerry -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On Sun, 30 Jan 2011 12:51:20 -0500, Gerald Britton wrote: Hi all, Today I was thinking about a problem I often encounter. Say that I have (seems I often do!) a deeply nested object, by which I mean object within object with object, etc. For example: x = some.deeply.nested.object.method (some.other.deeply.nested.object.value) Well, that's extreme but I've worked with code approaching that level of nested-ness. Then you're probably living in a state of sin, programming-wise, and you should stop doing that! You are violating the Law of Demeter. One dot, good. Two, acceptable. Three is a code smell. Four is a code reek. The Law of Demeter (more of a guideline than a law, really) says: If you want to get your dog to walk, call the dog. Don't talk to its legs, it confuses the dog and doesn't get it anywhere. http://en.wikipedia.org/wiki/Law_of_Demeter Another analogy: if you have to pay the paperboy for delivering the newspaper, you don't let him reach into your pocket, take out your wallet, open the wallet, take out whatever money he feels like, and put the wallet back. http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper- boy/demeter.pdf Despite my comment above, the Law of Demeter is not *really* a dot- counting exercise, although that's a handy short-cut for detecting potential problems. It can also apply to other data structures. If you've every seen C or Pascal code where you have a pointer to a pointer to a pointer to a pointer to a pointer to a pointer to some data, you've seen a violation. Consider your example: some.other.deeply.nested.object.value This is very tightly coupled code: the caller, who knows about the object `some`, needs to know the internal details of not just `some` but also `other`, `deeply`, `nested`, and `object`. As a basic principle, this is poor design! Which would you rather deal with? car.start() car.ignition.turn(key).connect(car.starter(battery), car.spark_plug) In particular, using temporary variables merely disguises the problem: temp = some.other temp = temp.deeply.nested x = temp.object.value Even though you never use more than two dots, you still have tight coupling. The point of Demeter is not to save dots (they're a renewable resource) but to reduce tight coupling. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On 1/30/11 1:13 PM, rantingrick wrote: On Jan 30, 12:53 pm, Stephen Hansen me+list/pyt...@ixokai.io wrote: OH MY GOD. How can someone be expected to understand what a function does! Yes, and also how decorators word and generators work, and ... Be serious! You can't expect that of them. I don't. I don't expect anyone to write 10 lines of obfuscation code when just two will suffice. Maybe you should join the perl group as they would proud! Riiight. suffice doesn't mean what you think it means. Generally, if something suffices -- it actually, you know, ... works. My four lines of setup can get put into a library and treated as a recipe if they don't want to get into understanding generators or decorators: then its two lines to use, and those two lines are exactly like your two lines except for two little details: 1. They add a function call to the syntax. 2. They actually work. The OP doesn't have to understand decorators or generators if he doesn't want to: though I encourage him to do so, as they are beautiful and elegant tools that can very clearly and concisely help solve a lot of problems. Now, me? I wouldn't use the recipe, as I originally said in my response. I'd just use a local variable. But the OP didn't like that, and he wanted some indenting and whitespace to clearly demarcate where he intended to use the local. So I gave him a way to do that. You gave him... uh, what was it again? Oh, right. Nothing. As usual. -- Stephen Hansen ... Also: Ixokai ... Mail: me+list/python (AT) ixokai (DOT) io ... Blog: http://meh.ixokai.io/ signature.asc Description: OpenPGP digital signature -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
I'd bet you would stress your point Steven! But you don't need to persuade me, I do already agree. I just meant to say that, when the advantage is little, there's no need to rewrite a working function. And that with modern CPUs, if tests take so little time, that even some redundant one is not so much of a nuisance. in your working example, the payload is just a couple of integer calculations, that take very little time too. So the overhead due to redundant if tests does show clearly. And also in that not-really-real situation, 60% overhead just meant less than 3 seconds. Just for the sake of discussion, I tried to give both functions some plough to pull, and a worst-case situation too: t1 = Timer('for x in range(100): print func1(0),', ... 'from __main__ import func1') t2 = Timer('for x in range(100): print func2(0),', ... 'from __main__ import func2') min(t1.repeat(number=1, repeat=1)) -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 53.011015366479114 min(t2.repeat(number=1, repeat=1)) -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 47.55442856564332 that accounts for a scant 11% overhead, on more than one million tests per cycle. That said, let's make really clear that I would heartily prefer func2 to func1, based both on readability and speed. Thank you for having spent some time playing with me! Francesco On 19/12/2010 1.05, Steven D'Aprano wrote: Well, let's try it with a working (albeit contrived) example. This is just an example -- obviously I wouldn't write the function like this in real life, I'd use a while loop, but to illustrate the issue it will do. def func1(n): result = -1 done = False n = (n+1)//2 if n%2 == 1: result = n done = True if not done: n = (n+1)//2 if n%2 == 1: result = n done = True if not done: n = (n+1)//2 if n%2 == 1: result = n done = True if not done: for i in range(100): if not done: n = (n+1)//2 if n%2 == 1: result = n done = True return result def func2(n): n = (n+1)//2 if n%2 == 1: return n n = (n+1)//2 if n%2 == 1: return n n = (n+1)//2 if n%2 == 1: return n for i in range(100): n = (n+1)//2 if n%2 == 1: return n return -1 Not only is the second far more readable that the first, but it's also significantly faster: from timeit import Timer t1 = Timer('for i in range(20): x = func1(i)', ... 'from __main__ import func1') t2 = Timer('for i in range(20): x = func2(i)', ... 'from __main__ import func2') min(t1.repeat(number=10, repeat=5)) 7.3219029903411865 min(t2.repeat(number=10, repeat=5)) 4.530779838562012 The first function does approximately 60% more work than the first, all of it unnecessary overhead. -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On Sat, 18 Dec 2010 19:59:45 -0800, Carl Banks wrote: On Dec 17, 12:23 am, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Thu, 16 Dec 2010 20:32:29 -0800, Carl Banks wrote: Even without the cleanup issue, sometimes you want to edit a function to affect all return values somehow. If you have a single exit point you just make the change there; if you have mulitple you have to hunt them down and change all of them--if you remember to. I just got bit by that one. If your function has so many exit points that you can miss some of them while editing, your function is too big, does too much, or both. Sanctimonious much? In the real world, people miss things and make mistakes and not necessarily because they are working on something too complex to handle. It happens. Really? I had no idea. I've never made a misteak, I asumed evrybody else was equally brilliant. No, wait, there was that one time... *wink* Of course people make mistakes. So what's your point? The point I was trying to make is that rather than encouraging an idiom (only one return statement, even if the algorithm is more clearly written with multiple exists) that leads to more complex, less efficient code just in case you might someday need to modify the return result, there are simple alternatives that avoid the need for anti-patterns like copy- and-paste coding or enforced single exit point. I gave two: - refactor the complex code so that it's less complex (e.g. instead of 20 exit points, which makes it easy to miss one or two, refactor it so there are two or three exit points); or if that's not practical: - wrap it in a decorator that performs the post-processing you need. Both can be simple, effective and Pythonic. Neither require the coder to use an artificial idiom just in case of some future need. The decorator solution works even if you don't have access to the source code, or if the function is a complex black box that nobody understands well enough to touch. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On 17/12/2010 0.51, Steven D'Aprano wrote: Don't get me wrong... spaghetti code is*bad*. But there are other ways of writing bad code too, and hanging around inside a function long after you've finished is also bad: def function(arg): done = False do_something() if some_condition: result = finished done = True if not done: do_something_else() if another_condition: result = now we're finished done = True if not done: do_yet_more_work() if third_condition: result = finished this time for sure done = True if not done: for i in range(100): if not done: do_something_small() if yet_another_condition: result = finally done! done = True return result It's far more complicated than it need be, and does*lots* of unnecessary work. This can be written more simply and efficiently as: def function(arg): do_something() if some_condition: return finished do_something_else() if another_condition: return now we're finished do_yet_more_work() if third_condition: return finished this time for sure for i in range(100): do_something_small() if yet_another_condition: return finally done! I agree to your point, but I'm afraid you chose a wrong example (AFAIK, and that's not much). Sure, the second version of function(arg) is much more readable, but why do you think the first one would do *lots* of unnecessary work? All the overhead in that function would be: if some_condition, three IF tests, and you know that's NOT a lot! if no conditions were met, (worst case) the first version would return an exception (unless result was globally defined) while the second would happily return None. Apart from this, the overhead in the first one would amount to one million IF tests, again not a lot these days. I don't think I would rewrite that function, if I found it written in the first way... I don't mean that the fist example is better, just I'm sure you could imagine a more compelling proof of your concept. Maybe there's something I don't know... in that case, please enlighten me! Francesco -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On Sat, 18 Dec 2010 12:29:31 +0100, Francesco wrote: [...] I agree to your point, but I'm afraid you chose a wrong example (AFAIK, and that's not much). Sure, the second version of function(arg) is much more readable, but why do you think the first one would do *lots* of unnecessary work? All the overhead in that function would be: if some_condition, three IF tests, and you know that's NOT a lot! Well, let's try it with a working (albeit contrived) example. This is just an example -- obviously I wouldn't write the function like this in real life, I'd use a while loop, but to illustrate the issue it will do. def func1(n): result = -1 done = False n = (n+1)//2 if n%2 == 1: result = n done = True if not done: n = (n+1)//2 if n%2 == 1: result = n done = True if not done: n = (n+1)//2 if n%2 == 1: result = n done = True if not done: for i in range(100): if not done: n = (n+1)//2 if n%2 == 1: result = n done = True return result def func2(n): n = (n+1)//2 if n%2 == 1: return n n = (n+1)//2 if n%2 == 1: return n n = (n+1)//2 if n%2 == 1: return n for i in range(100): n = (n+1)//2 if n%2 == 1: return n return -1 Not only is the second far more readable that the first, but it's also significantly faster: from timeit import Timer t1 = Timer('for i in range(20): x = func1(i)', ... 'from __main__ import func1') t2 = Timer('for i in range(20): x = func2(i)', ... 'from __main__ import func2') min(t1.repeat(number=10, repeat=5)) 7.3219029903411865 min(t2.repeat(number=10, repeat=5)) 4.530779838562012 The first function does approximately 60% more work than the first, all of it unnecessary overhead. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On Dec 17, 12:23 am, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Thu, 16 Dec 2010 20:32:29 -0800, Carl Banks wrote: Even without the cleanup issue, sometimes you want to edit a function to affect all return values somehow. If you have a single exit point you just make the change there; if you have mulitple you have to hunt them down and change all of them--if you remember to. I just got bit by that one. If your function has so many exit points that you can miss some of them while editing, your function is too big, does too much, or both. Sanctimonious much? In the real world, people miss things and make mistakes and not necessarily because they are working on something too complex to handle. It happens. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On Thu, 16 Dec 2010 20:32:29 -0800, Carl Banks wrote: Even without the cleanup issue, sometimes you want to edit a function to affect all return values somehow. If you have a single exit point you just make the change there; if you have mulitple you have to hunt them down and change all of them--if you remember to. I just got bit by that one. If your function has so many exit points that you can miss some of them while editing, your function is too big, does too much, or both. Refactor and simplify. Or wrap the function in a decorator: def affect_all_return_values(func): @functools.wraps(func) def inner(*args, **kwargs): result = func(*args, **kwargs) do_something_to(result) return result return inner @affect_all_return_values def my_big_complicated_function(args): do_something_with_many_exit_points() -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
John Gordon wrote: (This is mostly a style question, and perhaps one that has already been discussed elsewhere. If so, a pointer to that discussion will be appreciated!) When I started learning Python, I wrote a lot of methods that looked like this: def myMethod(self, arg1, arg2): if some_good_condition: if some_other_good_condition: if yet_another_good_condition: do_some_useful_stuff() exitCode = good1 else: exitCode = bad3 else: exitCode = bad2 else: exitCode = bad1 return exitCode But lately I've been preferring this style: def myMethod(self, arg1, arg2): if some_bad_condition: return bad1 elif some_other_bad_condition: return bad2 elif yet_another_bad_condition: return bad3 do_some_useful_stuff() return good1 I like this style more, mostly because it eliminates a lot of indentation. However I recall one of my college CS courses stating that one entry, one exit was a good way to write code, and this style has lots of exits. Are there any concrete advantages of one style over the other? Thanks. What about, def myMethod(): for condition, exitCode in [ (cond1, 'error1'), (cond2, 'very bad error'), ]: if not condition: break else: do_some_usefull_stuff() # executed only if the we never hit the break statement. exitCode = good1 return exitCode This version uses the 'for ... else' statement. You can easily add conditions by simply adding a line in the list, that's it. Note that this code uses a shadow declaration of exitCode in the for loop. If you're not comfortable with that, you'll have to use a properly 'declared' variable retCode and write retCode = exitCode before breaking. Actually I would advise to do so. JM -- http://mail.python.org/mailman/listinfo/python-list
RE: If/then style question
-Original Message- What about, def myMethod(): for condition, exitCode in [ (cond1, 'error1'), (cond2, 'very bad error'), ]: if not condition: break else: do_some_usefull_stuff() # executed only if the we never hit the break statement. exitCode = good1 return exitCode I reply - This is interesting, but I don't understand it (which speaks volumes about the level of my understanding of Python). First, just to clarify, I don't think the indentation I saw was what was originally posted. The else must be indented to match the if, and the two statements under else are in the else block. The return statement is indented at the same level as the for statement, so that it will be executed after the for loop exits. Correct? Now, the for loop will set condition to cond1 and exitCode to 'error1'. Then it checks the contents of the condition variable. But what does not variable_name by itself mean? I'm guessing that it checks that the variable refers to an object. So, the first time through, condition refers to cond1, the if condition is false, and the else block gets executed, and exitCode is changed to refer to good1. The next time through the loop, condition is set to refer to cond2 and exitCode is set to refer to 'very bad error'. Again, condition is refering to something, so the else block is executed and we do useful stuff again, which is probably not helpful and could well be harmful. exitCode is set to good1, we're finished with the loop, and we return exitCode. What happens if we try to do useful stuff, and we can't? Where does the error indication get set? And once it does get set, the only way we can exit the for loop is for condition to not refer to anything. How can that happen? Thank you very much for your explanation and your patience with one who only uses Python in very simplistic ways. RobR -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On Fri, 17 Dec 2010 09:09:49 -0500, Rob Richardson wrote: First, just to clarify, I don't think the indentation I saw was what was originally posted. The else must be indented to match the if, and the two statements under else are in the else block. The return statement is indented at the same level as the for statement, so that it will be executed after the for loop exits. Correct? I think that what you are missing is that for-loops can include an else clause too, like this: for x in (1,2,3): ... print(x) ... else: ... print(finished) ... 1 2 3 finished The else block runs after the for block, unless you exit the entire block by returning, raising an exception, or using break: for x in (1,2,3): ... print(x) ... if x == 3: break ... else: ... print(finished) ... 1 2 3 Does that clear up what is going on? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
Rob Richardson wrote: -Original Message- What about, def myMethod(): for condition, exitCode in [ (cond1, 'error1'), (cond2, 'very bad error'), ]: if not condition: break else: do_some_usefull_stuff() # executed only if the we never hit the break statement. exitCode = good1 return exitCode I reply - This is interesting, but I don't understand it (which speaks volumes about the level of my understanding of Python). First, just to clarify, I don't think the indentation I saw was what was originally posted. The else must be indented to match the if, and the two statements under else are in the else block. No, the else is indented to the for loop. for ... else is a python statement, the else block is executed only if the loop did never break. http://docs.python.org/reference/compound_stmts.html#for The return statement is indented at the same level as the for statement, so that it will be executed after the for loop exits. Correct? Now, the for loop will set condition to cond1 and exitCode to 'error1'. Then it checks the contents of the condition variable. But what does not variable_name by itself mean? condition is a bool value. if not condition is evaluated to True, if the condition is False. condition = False not condition = True condition = ('Foo' == 'Foo') not condition = False [snip] RobR My mail client could have messed up with the indentation. Here is the code: http://paste-it.net/public/t8a4acd/python/ JM -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On Thu, Dec 16, 2010 at 6:51 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: ... Functions always have one entry. The only way to have multiple entry points is if the language allows you to GOTO into the middle of a function, and Python sensibly does not allow this. The one entry, one exit rule comes from the days when people would routinely write spaghetti code, jumping into and out of blocks of code without using functions at all. Only 99.7% true. Fortran still allows the appalling ENTRY statement. -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On 12/17/2010 9:38 AM, Steven D'Aprano wrote: On Fri, 17 Dec 2010 09:09:49 -0500, Rob Richardson wrote: First, just to clarify, I don't think the indentation I saw was what was originally posted. The else must be indented to match the if, and the two statements under else are in the else block. The return statement is indented at the same level as the for statement, so that it will be executed after the for loop exits. Correct? I think that what you are missing is that for-loops can include an else clause too, like this: for x in (1,2,3): ... print(x) ... else: ... print(finished) ... 1 2 3 finished The else block runs after the for block, unless you exit the entire block by returning, raising an exception, or using break: for x in (1,2,3): ... print(x) ... if x == 3: break ... else: ... print(finished) ... 1 2 3 Does that clear up what is going on? This construct appears to be unpopular in actual use, and when it comes up in classes and seminars there is always interesting debate as people discuss potential uses and realise there are useful applications. I think the choice of keyword is probably not Guido's crowning language achievement, but then since the English keywords don't make natural sense to those who speak other languages it's at least fair that there should be one that isn't totally natural to English speakers. A small price to pay for all the other keywords not being Dutch. regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 PyCon 2011 Atlanta March 9-17 http://us.pycon.org/ See Python Video! http://python.mirocommunity.org/ Holden Web LLC http://www.holdenweb.com/ -- http://mail.python.org/mailman/listinfo/python-list
RE: If/then style question
My thanks for pointing out the existence of the else: suite in the for statement. However, I remain confused. For reference, here's the original code: def myMethod(): for condition, exitCode in [ (cond1, 'error1'), (cond2, 'very bad error'), ]: if not condition: break else: do_some_usefull_stuff() # executed only if the we never hit the break statement. exitCode = good1 return exitCode What do we know about cond1 and cond2? Do they have to be assigned before this for statement is executed? The sample code doesn't show it. The loop is going to to execute once for condition = cond1 and exitCode = 'error1'. The only thing it's going to do is check to see what condition is. Since we can assume (I hope) that cond1 is not false, then the for loop continues. Now condition = cond2 and exitCode = 'very bad error'. The if condition is still false, so the loop continues. We've come to the end now, and the else: suite is executed. We finally do some useful stuff and exitCode = good1. (Should that have been in quotes, or doesn't it matter?) But now the for loop's job is done and we return the exitCode, which at this point is good1. But I still don't understand what happens if we can't do useful stuff. Where does an error code get set, and where is that error code checked? We don't have a chance to check it in the for loop, because once we're in the else: suite the loop condition is never rechecked. Or is it? Thanks again! RobR -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On 17/12/2010 15:53, Steve Holden wrote: [... snip example of for-else ...] This construct appears to be unpopular in actual use, and when it comes up in classes and seminars there is always interesting debate as people discuss potential uses and realise there are useful applications. I use this not infrequently, and I like it when it seems to be an elegant way to express the code path. But I still misremember from time to time and assume that the else clause fires when the for loop is empty. TJG -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
Jean-Michel Pichavant jeanmic...@sequans.com writes: What about, def myMethod(): for condition, exitCode in [ (cond1, 'error1'), (cond2, 'very bad error'), ]: if not condition: break else: do_some_usefull_stuff() # executed only if the we never hit the break statement. exitCode = good1 return exitCode This version uses the 'for ... else' statement. For..else always has seemed ugly and confusing to me, as does that thing of using the captured loop indexes after the loop finishes. I'd prefer a more functional style (untested): def myMethod(): def success(): do_some_usefull_stuff() return good1 cond_table = [ (cond1, lambda: 'error1'), (cond2, lambda: 'very bad error'), (True, success) ] func = next(f for c,f in cond_table if c) return func() This uses the next() builtin from Python 2.6. You could make it more concise: def myMethod(): cond_table = [ (cond1, lambda: 'error1'), (cond2, lambda: 'very bad error'), (True, lambda: (do_some_usefull_stuff(), good1)[1]) ] return next(f for c,f in cond_table if c)() -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
Rob Richardson wrote: My thanks for pointing out the existence of the else: suite in the for statement. However, I remain confused. For reference, here's the original code: def myMethod(): for condition, exitCode in [ (cond1, 'error1'), (cond2, 'very bad error'), ]: if not condition: break else: do_some_usefull_stuff() # executed only if the we never hit the break statement. exitCode = good1 return exitCode What do we know about cond1 and cond2? Do they have to be assigned before this for statement is executed? The sample code doesn't show it. cond1 and cond2 should be expressions of some sort, e.g. check_files() or feedback (feedback being a variable of some sort). The loop is going to to execute once for condition = cond1 and exitCode = 'error1'. The only thing it's going to do is check to see what condition is. Since we can assume (I hope) that cond1 is not false, then the for loop continues. Now condition = cond2 and exitCode = 'very bad error'. The if condition is still false, so the loop continues. We've come to the end now, and the else: suite is executed. We finally do some useful stuff and exitCode = good1. (Should that have been in quotes, or doesn't it matter?) But now the for loop's job is done and we return the exitCode, which at this point is good1. But I still don't understand what happens if we can't do useful stuff. Where does an error code get set, and where is that error code checked? We don't have a chance to check it in the for loop, because once we're in the else: suite the loop condition is never rechecked. Or is it? You have outlined what happens when cond1 and cond2 both evaluate to True -- what happens if, say, cond2 evaluates to False? . . . . . if not cond2 becomes True, we hit the break, do not do do_some_usefull_stuff(), but proceed to return exitCode -- and exitCode was set in the for loop to 'very bad error' when condition was set to cond2. The exitCode no longer needs to be checked inside the function, because there is no chance of do_some_useful_stuff running if any of the conditions are False. Hope this helps. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On 12/17/2010 11:13 AM, Tim Golden wrote: On 17/12/2010 15:53, Steve Holden wrote: [... snip example of for-else ...] This construct appears to be unpopular in actual use, and when it comes up in classes and seminars there is always interesting debate as people discuss potential uses and realise there are useful applications. I use this not infrequently, and I like it when it seems to be an elegant way to express the code path. But I still misremember from time to time and assume that the else clause fires when the for loop is empty. Yes, that's a common misconception. The classical use is something like for item in possibilities: if item == target: break else: raise NotFound(Didn't find it) Though of course arguably that logic might be expressed in other ways, such as if target not in possibilities: raise NotFound(Didn't find it) regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 PyCon 2011 Atlanta March 9-17 http://us.pycon.org/ See Python Video! http://python.mirocommunity.org/ Holden Web LLC http://www.holdenweb.com/ -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
Steve Holden st...@holdenweb.com writes: I think the choice of keyword is probably not Guido's crowning language achievement, I remember the behaviour by considering a typical application: for thing in things: if shinyp(thing): break else: raise DullError, 'nothing shiny found' In this kind of search loop, `break' signifies a kind of successful completion: the `for' loop can be considered to be a test acting over an iterable, and `else' therefore denotes the action if the test fails. I don't know whether that's the official intuition, or even if there is an official intuition, but it works well enough for me. I'm quite fond of Python's extra `else' clauses in `for' and (particularly) `try'. -- [mdw] -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
Tim Golden m...@timgolden.me.uk writes: On 17/12/2010 15:53, Steve Holden wrote: [... snip example of for-else ...] This construct appears to be unpopular in actual use, and when it comes up in classes and seminars there is always interesting debate as people discuss potential uses and realise there are useful applications. I use this not infrequently, and I like it when it seems to be an elegant way to express the code path. But I still misremember from time to time and assume that the else clause fires when the for loop is empty. I use it from time to time, even though, like you, I used to always be unsure when the else: suite would be executed. I now remember this idiom as the break else construct: either the loop breaks, or the else: suite is executed. -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
I now remember this idiom as the break else construct: either the loop breaks, or the else: suite is executed. A perfect description. Malcolm -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On 2010-12-16, Stefan Sonnenberg-Carstens stefan.sonnenb...@pythonmeister.com wrote: The advantage in latter case is fewer operations, because you can skip the assignments, and it is more readable. The one entry, one exit is an advice. Not a law. Your code is OK. As long as it works ;-) Even that last bit isn't that important. Give me code that's easy-to-read and doesn't work rather code that works and can't be read any day. -- Grant Edwards grant.b.edwardsYow! What's the MATTER at Sid? ... Is your BEVERAGE gmail.comunsatisfactory? -- http://mail.python.org/mailman/listinfo/python-list
Re: If/then style question
On 2010-12-16, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: On Thu, 16 Dec 2010 21:49:07 +, John Gordon wrote: (This is mostly a style question, and perhaps one that has already been discussed elsewhere. If so, a pointer to that discussion will be appreciated!) When I started learning Python, I wrote a lot of methods that looked like this: def myMethod(self, arg1, arg2): if some_good_condition: if some_other_good_condition: if yet_another_good_condition: do_some_useful_stuff() exitCode = good1 else: exitCode = bad3 else: exitCode = bad2 else: exitCode = bad1 return exitCode It doesn't look like you were learning Python. It looks like you were learning C with Python syntax :( Let's not blame C for bad program structure. No good C programmer would use that construct either. One choice in C would look like this: if (some_condition) return code1; if (other_condition) return code2; if (condition3) return code3; //do whatever work really needs to be done here. return successCode; Or, if there's cleanup that needs to be done, then you raise a an exception: if (condition1) { ret = code1; goto errexit; } if (condition2) { ret = code2; goto errexit; } if (condition3) { ret = code3; goto errexit; } // do the normal bit of work errexit: //cleanup return ret; -- Grant Edwards grant.b.edwardsYow! Awright, which one of at you hid my PENIS ENVY? gmail.com -- http://mail.python.org/mailman/listinfo/python-list
RE: If/then style question
-Original Message- You have outlined what happens when cond1 and cond2 both evaluate to True -- what happens if, say, cond2 evaluates to False? - I reply And the light goes on! (And palm strikes forehead.) I was thinking that the error we were processing was raised by the do_some_useful_stuff() function. But the whole purpose of this thread was to evaluate error conditions that might have been set before we do useful stuff! Which, of course, was what the original poster was asking. My thanks again for your patience. RobR -- http://mail.python.org/mailman/listinfo/python-list