2.X functools.update_wrapper dislikes missing function attributes
I noticed a behavior in Jython 2.5.2 that's arguably an implementation bug, but I'm wondering if it's something to be fixed for all versions of Python. I was wanting to decorate a Java instance method, and discovered that it didn't have a __module__ attribute. This caused the following message: File "C:\jython2.5.2\Lib\functools.py", line 33, in update_wrapper setattr(wrapper, attr, getattr(wrapped, attr)) AttributeError: 'instancemethod' object has no attribute '__module__' The relevant code is: for attr in assigned: setattr(wrapper, attr, getattr(wrapped, attr)) for attr in updated: getattr(wrapper, attr).update(getattr(wrapped, attr, {})) Note that attributes to be updated get a default value. I'm proposing that attributes to be assigned do the same, most likely an empty string. A non-string value (such as None) could break anything expecting a string value, so it seems like a bad idea. Python 3.2 catches AttributeError and passes. I don't like this solution. While it prevents any attributes from being added to the wrapper, the wrapper likely has its own values (at least for the default attributes) and using those values could cause confusion. Any opinions? -- http://mail.python.org/mailman/listinfo/python-list
Re: 2.X functools.update_wrapper dislikes missing function attributes
I just noticed an old issue that relate to this: http://bugs.python.org/issue3445 This dates back to 2008 and is marked as fixed, but my copies of Python 2.5.4 and 2.7.1 don't seem to implement it. I'll try to dig further. -- http://mail.python.org/mailman/listinfo/python-list
Re: Microsoft Hatred FAQ
David Schwartz wrote: > "Mike Meyer" <[EMAIL PROTECTED]> wrote in message > news:[EMAIL PROTECTED] > Morally, lying in court is a tough one. For example, suppose you are in > a court case with someone who is definitely lying in court. You are in the > right, but it's clear the court won't believe you in the face of the lying > and faked evidence. In this case, is lying in court fraud? Or is it > justified in defense against an attacker willing to use fraud against you? > So this isn't quite in the same category as force or fraud, because the > court has the ability to balance credibility and control damage. No such > balancing is available against a bullet in flight. Lying in court isn't fraud. It is perjury. There are laws against it with pretty stiff penalties, because it subverts the court system. Committing perjury to defend yourself against fraud will often cause any conviction and punishment relating to the fraud to be erased. So, I'd say no, it isn't justified. Instead, you try to prove that the other person is lying. Lawyers do this all the time; it's part of their job and it's called discrediting the witness. BTW, if you want an excellent example of officers of Microsoft falsifying evidence in a trial, you need look no further that here: http://wired-vig.wired.com/news/politics/0,1283,17689,00.html and here: http://www.wired.com/news/politics/0,1283,17938,00.html -- http://mail.python.org/mailman/listinfo/python-list
Python 3000: Standard API for archives?
I'm a relative newbie to Python, so please bear with me. There are currently two standard modules used to access archived data: zipfile and tarfile. The interfaces are completely different. In particular, script wanting to analyze different types of archives must duplicate substantial pieces of logic. The problem is not limited to method names; it includes how stat-like information is accessed. I think it would be a good thing if a standardized interface existed, similar to PEP 247. This would make it easier for one script to access multiple types of archives, such as RAR, 7-Zip, ISO, etc. In particular, a single factory class could produce PEP 302 import hooks for future as well as current archive formats. I think that an archive module adhering to the standard should adopt a least-common-denominator approach, initially supporting read-only access without seek, i.e. tar files on actual tape. For applications that require a seek method (such as importers) a standard wrapper class could transparently cache archive members in temp files; this would fit in well with Python 3000's rewrite of the I/O interface to support stackable interfaces. To this end, we'd need is_seekable and is_writable attributes for both the module and instances (moduel level would declare if something is possible, not if it is always true). Most importantly, all archive modules should provide a standard API for accessing their individual files via a single archive_content class that provides a standard 'read' method. Less importantly but nice to have would be a way for archives to be auto-magically scanned during walks of directories. Feedback? -- http://mail.python.org/mailman/listinfo/python-list
Re: need help with re module
Gabriel Genellina wrote: > En Wed, 20 Jun 2007 17:56:30 -0300, David Wahler <[EMAIL PROTECTED]> > escribió: > >> On 6/20/07, Gabriel Genellina <[EMAIL PROTECTED]> wrote: >> [snip] >> I agree that BeautifulSoup is probably the best tool for the job, but >> this doesn't sound right to me. Since the OP doesn't care about tags >> being properly nested, I don't see why a regex (albeit a tricky one) >> wouldn't work. For example: >> [snip] >> >> Granted, this misses out a few things (e.g. DOCTYPE declarations), but >> those should be straightforward to handle. > > It doesn't handle a lot of things. For this input (not very special, > just a few simple mistakes): > > > http://foo.com/baz.html>click here > What if price<100? You lose. > What if HitPoints<-10? You are dead. > Assignment: target <-- any_expression > Just a few last words. > > > the BeautifulSoup version gives: > > click here > What if price<100? You lose. > What if HitPoints<-10? You are dead. > Assignment: target <-- any_expression > Just a few last words. > > and the regular expression version gives: > > http://foo.com/baz.html>click here > What if priceWhat if HitPointsAssignment: target > > Clearly the BeautifulSoup version gives the "right" result, or the > "expected" one. > It's hard to get that with only a regular expression, you need more > power; and BeautifulSoup fills the gap. Speak for yourself. If I'm writing an HTML syntax checker, I think I'll skip BeautifulSoup and use something that gives me the results that I expect, not the results that you expect. -- http://mail.python.org/mailman/listinfo/python-list
Re: Re-raising exceptions with modified message
On Jul 5, 8:53 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote: > What is the best way to re-raise any exception with a message > supplemented with additional information (e.g. line number in a > template)? Let's say for simplicity I just want to add "sorry" to every > exception message. My naive solution was this: > > try: > ... > except Exception, e: > raise e.__class__, str(e) + ", sorry!" > > This works pretty well for most exceptions, e.g. > > >>> try: > ... 1/0 > ... except Exception, e: > ... raise e.__class__, str(e) + ", sorry!" > ... > Traceback (most recent call last): >File "", line 4, in > ZeroDivisionError: integer division or modulo by zero, sorry! > > But it fails for some exceptions that cannot be instantiated with a > single string argument, like UnicodeDecodeError which gets "converted" > to a TypeError: > > >>> try: > ... unicode('\xe4') > ... except Exception, e: > ... raise e.__class__, str(e) + ", sorry!" > ... > Traceback (most recent call last): >File "", line 4, in > TypeError: function takes exactly 5 arguments (1 given) > > Another approach is using a wrapper Extension class: > > class SorryEx(Exception): > def __init__(self, e): > self._e = e > def __getattr__(self, name): > return getattr(self._e, name) > def __str__(self): > return str(self._e) + ", sorry!" > > try: > unicode('\xe4') > except Exception, e: > raise SorryEx(e) > > But then I get the name of the wrapper class in the message: > > __main__.SorryEx: 'ascii' codec can't decode byte 0xe4 in position 0: > ordinal not in range(128), sorry! > > Yet another approach would be to replace the __str__ method of e, but > this does not work for new style Exceptions (Python 2.5). > > Any suggestions? > > -- Chris Can "try" statements be used in "except" clauses? It appears so, thus a hybrid approach might work well enough. try: ... except Exception, e: try: raise e.__class__, str(e) + ", sorry!" except TypeError: raise SorryEx(e) That leaves the issue of the name being changed for UnicodeDecodeError, which might be fixable by diddling with __name__ properties. Or perhaps SorryEx needs to be a factory that returns exception classes; the last line would be "SorryEx(e)()". I'll have to play with this a bit. -- http://mail.python.org/mailman/listinfo/python-list
Re: Re-raising exceptions with modified message
On Jul 7, 4:13 pm, samwyse <[EMAIL PROTECTED]> wrote: > On Jul 5, 8:53 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote: > > > What is the best way to re-raise any exception with a message > > supplemented with additional information (e.g. line number in a > > template)? [...] > That leaves the issue of the name being changed for > UnicodeDecodeError, which might be fixable by diddling with __name__ > properties. Or perhaps SorryEx needs to be a factory that returns > exception classes; the last line would be "SorryEx(e)()". I'll have > to play with this a bit. OK, the following mostly works. You probably want the factory to copy more of the original class into the SorryEx class each time, since someone catching an exception may expect to look at things besides its string representation. def SorryFactory(e): class SorryEx(Exception): def __init__(self): self._e = e def __getattr__(self, name): return getattr(self._e, name) def __str__(self): return str(self._e) + ", sorry!" SorryEx.__name__ = e.__class__.__name__ return SorryEx def test(code): try: code() except Exception, e: try: raise e.__class__, str(e) + ", sorry!" except TypeError: raise SorryFactory(e)() test(lambda: unicode('\xe4')) -- http://mail.python.org/mailman/listinfo/python-list
Re: Re-raising exceptions with modified message
On Jul 5, 8:53 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote: > What is the best way to re-raise any exception with a message > supplemented with additional information (e.g. line number in a > template)? Let's say for simplicity I just want to add "sorry" to every > exception message. OK, this seems pretty minimal, yet versatile. It would be nice to be able to patch the traceback, but it turns out that it's fairly hard to do. If you really want to do that, however, go take a look at http://lucumr.pocoo.org/cogitations/2007/06/16/patching-python-tracebacks-part-two/ # Written by Sam Denton <[EMAIL PROTECTED]> # You may use, copy, or distribute this work, # as long as you give credit to the original author. def rewriten_exception(old, f): class Empty(): pass new = Empty() new.__class__ = old.__class__ new.__dict__ = old.__dict__.copy() new.__str__ = f return new def test(code): try: code() except Exception, e: raise rewriten_exception(e, lambda: str(e) + ", sorry!") test(lambda: unicode('\xe4')) test(lambda: 1/0) -- http://mail.python.org/mailman/listinfo/python-list
Re: what is wrong with that r"\"
On Jul 4, 7:15 am, Matthieu TC <[EMAIL PROTECTED]> wrote: > May I suggest giving the possibility to use any delimiter for a raw string? > just like in Vi or ruby. > > Vi: > %s_a_b_g is valid and so is %s/a/b/g > > Ruby: > %q{dj'\ks'a\'"} or %q-dj'\ks'a\'"- > > So as long as your regex does not use all the valid characters, readability > is maintained. first, you'll need a way to flag that something is an arbitrarily quoted string; 'r' is taken, so let's use 'q'. next, you need to distinguish strings from variables, perhaps by adding a flag to all variables; $ should do nicely and has some historical precident. once you've done all that, you can write something like this: $q = q|this so-called "string" doesn't use conventional quotes| congratulations! you've just invented perl! -- http://mail.python.org/mailman/listinfo/python-list
Re: allow scripts to use .pth files?
On Jul 3, 9:35 am, Alan Isaac <[EMAIL PROTECTED]> wrote: > Suppose I have a directory `scripts`. > I'd like the scripts to have access to a package > that is not "installed", i.e., it is not on sys.path. > On this list, various people have described a variety > of tricks they use, but nobody has proposed a > pretty way to allow this. > I am therefore assuming there is not one. (?) > > How about allowing a `scripts.pth` file in such a `scripts` > directory, to work like a path configuration file? > (But to be used only when __name__=="__main__".) > Drawbacks? > > Alan Isaac before i can adequately shoot down your proposal, i need more information. first, how does the interpreter know to look in 'scripts' for your 'scripts.pyh' file and not in '.' or '~' or sys.argv[0] or someplace else? and you do know, don't you, that if you run 'scripts/ myscript.py' then 'scripts' is automagically prepended to the search path for modules? second, what's for format of this proposed file? does it contain the name of a single directory? is it one directory name per line? is it intended to be os-specific or will the same file work on windows, unix, vms and macos? third, is there anything special about the name? should i put a myscripts.pyh file in the myscripts directory? what if i have multiple .pyh files? if i may make some assumptions about the answers to the above, then this incantation might do somewhat more than what you've asked for (but what you actually want may be different): if __name__ == '__main__': import sys from os.path import split, join, expanduser for d in '.', split(sys.argv[0])[0], expanduser('~'): scripts_pyh = join(d, 'scripts.pyh') try: for each_line in open(scripts_pyh).readlines(): sys.path.append(each_line) except: pass personally, though, i would be more likely to use this and skip all of that 'scripts.pyh' nonsense: if __name__ == '__main__': import sys, os.path for d in '.', os.path.expanduser('~'): if os.path.isdir(d): sys.path.append(d) -- http://mail.python.org/mailman/listinfo/python-list
Re: Rats! vararg assignments don't work
On May 30, 7:29 am, Sion Arrowsmith <[EMAIL PROTECTED]> wrote: > samwyse <[EMAIL PROTECTED]> wrote: > >>samwysewrote: > >>>I thought that I'd try this: > >>> first, *rest = arglist > >>>Needless to say, it didn't work. > > [ ... ] > >My use-case is (roughtly) this: > > first, *rest = f.readline().split() > > return dispatch_table{first}(*rest) > > first, rest = f.readline().split(None, 1) > return dispatch_table{first}(*rest.split()) Hey, I like that! Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: allow scripts to use .pth files?
On Jul 8, 3:53 pm, John Machin <[EMAIL PROTECTED]> wrote: > I got the impression that the OP was suggesting that the interpreter > look in the directory in which it found the script. [...] > I got the impression that the problem was that the package was not > only not on sys.path but also not in the same directory as the script > that wanted to import it. Otherwise the OP's script.p?h file need only > contain ".\n" (or the path to the directory in which it resided!!), > and I doubt that he was proposing something so silly. And as I'm sure you realize, those two impression slightly contradict each other. Anyway, a small modification to my second approach would also work in the case looking for packages in a directory that's located somewhere relative to the one where the script was found: if __name__ == '__main__': import sys, os.path base = sys.path[0] for d in 'lib', 'modules': d2 = os.path.join(base, d) if os.path.isdir(d2): sys.path.append(d2) base = os.path.join(base, '..') for d in 'modules', 'lib': d2 = os.path.join(base, d) if os.path.isdir(d2): sys.path.append(d2) # for debugging print repr(sys.path) (BTW, this is such a fun script to type. My fingers keep typing 'os.path' where I mean 'sys.path' and vice versa.) -- http://mail.python.org/mailman/listinfo/python-list
Re: Re-raising exceptions with modified message
On Jul 8, 8:50 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote: > Did you run this? > With Py < 2.5 I get a syntax error, and with Py 2.5 I get: > > new.__class__ = old.__class__ > TypeError: __class__ must be set to a class > > -- Chris Damn, I'd have sworn I ran the final copy that I posted, but apparently I did manage to have a typo creep in as I was prettifying the code. You need to lose the '()' in the definition of Empty. (I'd orignally had it subclass Exception but discovered that it wasn't needed.) class Empty: pass I can't figure out the other complaint, though, as old.__class_ should be a class. I guess I need to upgrade; I am using PythonWin 2.4.3 (#69, Apr 11 2006, 15:32:42) [MSC v.1310 32 bit (Intel)] on win32. (Of course, at work they're still stuck on 2.4.2.) Printing type(old.__class__) gives me ; maybe using setattr(new, '__class__', old.__class__) instead of the assignment would work, or maybe it's a bug/feature introduced in 2.5. (Trying this code: class Empty(old.__class__): pass brings us back to the "TypeError: function takes exactly 5 arguments (0 given)" message that we're trying to avoid.) Anyway, running the corrected version under 2.4.X gives me this: Traceback (most recent call last): File "C:\Python24\Lib\site-packages\pythonwin\pywin\framework \scriptutils.py", line 310, in RunScript exec codeObject in __main__.__dict__ File "C:\Documents and Settings\dentos\Desktop\scripting \modify_message.py", line 19, in ? test(lambda: unicode('\xe4')) File "C:\Documents and Settings\dentos\Desktop\scripting \modify_message.py", line 16, in test raise modify_message(e, lambda: str(e) + ", sorry!") UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128), sorry! >>> -- http://mail.python.org/mailman/listinfo/python-list
Re: allow scripts to use .pth files?
On Jul 8, 3:53 pm, John Machin <[EMAIL PROTECTED]> wrote: > I'm curious whether you think that the OP's use of ".pth" was a typo, > and whether you have read this: >http://docs.python.org/lib/module-site.html I've read it, but not recently; the syntax of the .pyh files was in the back of my head. I had forgotten about the sitecustomize module, though. Unfortunately for the OP, while the documentation states, "After these path manipulations, an attempt is made to import a module named sitecustomize," the import is apparently done *before* the path to the script is prepended to sys.path. (My name isn't Luke, so I don't feel the need to read the source.) I'm guessing that the OP's real question is, "How does one do site customizations when one doesn't have write access to the site directories?" Lots of programs can be installed and run from ~/bin, but locating ~/lib can be hard, at least for arbitrary values of bin and lib. At this point, someone usually tells me to write a PEP; perhaps the OP would like to try his hand? In keeping with the spirit of the site customizations, I'd specify that all .pyh files get imported, not just one matching the name of the script. (This is more robust in the face of hard-links, packages consisting of multiple scripts, etc.) I'd also suggest an attempt to import a module named mycustomize after the path to the invoked script is prepended to sys.path. -- http://mail.python.org/mailman/listinfo/python-list
Re: allow scripts to use .pth files?
On Jul 12, 7:20 am, John Machin <[EMAIL PROTECTED]> wrote: > On Jul 12, 9:55 pm, samwyse <[EMAIL PROTECTED]> wrote: > > > On Jul 8, 3:53 pm, John Machin <[EMAIL PROTECTED]> wrote: > > > > I got the impression that the OP was suggesting that the interpreter > > > look in the directory in which it found the script. > > [...] > > > I got the impression that the problem was that the package was not > > > only not on sys.path but also not in the same directory as the script > > > that wanted to import it. Otherwise the OP's script.p?h file need only > > > contain ".\n" (or the path to the directory in which it resided!!), > > > and I doubt that he was proposing something so silly. > > > And as I'm sure you realize, those two impression slightly contradict > > each other. > > Your sureness is misplaced. Please explain. Oops, you're right. See my other post. -- http://mail.python.org/mailman/listinfo/python-list
Re: Re-raising exceptions with modified message
On Jul 12, 6:31 am, samwyse <[EMAIL PROTECTED]> wrote: > On Jul 8, 8:50 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote: > > > With Py 2.5 I get: > > > new.__class__ = old.__class__ > > TypeError: __class__ must be set to a class Hmmm, under Python 2.4.X, printing repr(old.__class__) gives me this: while under 2.5.X, I get this: So, let's try sub-classing the type: def modify_message(old, f): class Empty: pass new = Empty() print "old.__class__ =", repr(old.__class__) print "Empty =", repr(Empty) new.__class__ = Empty class Excpt(old.__class__): pass print "Excpt =", repr(Excpt) print "Excpt.__class__ =", repr(Excpt.__class__) new.__class__ = Excpt new.__dict__ = old.__dict__.copy() new.__str__ = f return new Nope, that gives us the same message: old.__class__ = Empty = Excpt = Excpt.__class__ = Traceback (most recent call last): [...] TypeError: __class__ must be set to a class Excpt ceratinly appears to be a class. Does anyone smarter than me know what's going on here? -- http://mail.python.org/mailman/listinfo/python-list
Assignments to __class_ broken in Python 2.5?
On Jul 12, 11:48 am, samwyse <[EMAIL PROTECTED]> wrote: > On Jul 12, 6:31 am,samwyse<[EMAIL PROTECTED]> wrote: > > > On Jul 8, 8:50 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote: > > > > With Py 2.5 I get: > > > > new.__class__ = old.__class__ > > > TypeError: __class__ must be set to a class > > Hmmm, under Python 2.4.X, printing repr(old.__class__) gives me this: > > while under 2.5.X, I get this: > > > So, let's try sub-classing the type: > > def modify_message(old, f): > class Empty: pass > new = Empty() > print "old.__class__ =", repr(old.__class__) > print "Empty =", repr(Empty) > new.__class__ = Empty > > class Excpt(old.__class__): pass > print "Excpt =", repr(Excpt) > print "Excpt.__class__ =", repr(Excpt.__class__) > new.__class__ = Excpt > > new.__dict__ = old.__dict__.copy() > new.__str__ = f > return new > > Nope, that gives us the same message: > > old.__class__ = > Empty = > Excpt = > Excpt.__class__ = > Traceback (most recent call last): > [...] > TypeError: __class__ must be set to a class > > Excpt certainly appears to be a class. Does anyone smarter than me > know what's going on here? OK, in classobject.h, we find this: #define PyClass_Check(op) ((op)->ob_type == &PyClass_Type) That seems straightforward enough. And the relevant message appears in classobject.c here: static int instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v) [...] if (strcmp(sname, "__class__") == 0) { if (v == NULL || !PyClass_Check(v)) { PyErr_SetString(PyExc_TypeError, "__class__ must be set to a class"); return -1; } Back in our test code, we got these: > Empty = > Excpt = The first class (Empty) passes the PyClass_Check macro, the second one (Excpt) evidently fails. I'll need to dig deeper. Meanwhile, I still have to wonder why the code doesn't allow __class_ to be assigned a type instead of a class. Why can't we do this in the C code (assuming the appropriate PyType_Check macro): if (v == NULL || !(PyClass_Check(v) || PyType_Check(v))) { -- http://mail.python.org/mailman/listinfo/python-list
Re: Assignments to __class_ broken in Python 2.5?
(Yes, I probably should have said CPython in my subject, not Python. Sorry.) On Jul 13, 12:56 am, samwyse <[EMAIL PROTECTED]> wrote: > OK, in classobject.h, we find this: > > #define PyClass_Check(op) ((op)->ob_type == &PyClass_Type) > > That seems straightforward enough. And the relevant message appears > in classobject.c here: > > static int > instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v) > [...] > if (strcmp(sname, "__class__") == 0) { > if (v == NULL || !PyClass_Check(v)) { > PyErr_SetString(PyExc_TypeError, >"__class__ must be set to a class"); > return -1; > } > > Back in our test code, we got these: > > > Empty = > > Excpt = > > The first class (Empty) passes the PyClass_Check macro, the second one > (Excpt) evidently fails. I'll need to dig deeper. Meanwhile, I still > have to wonder why the code doesn't allow __class_ to be assigned a > type instead of a class. Why can't we do this in the C code (assuming > the appropriate PyType_Check macro): > > if (v == NULL || !(PyClass_Check(v) || PyType_Check(v))) { After a good night's sleep, I can see that Empty is a "real" class; i.e. its repr() is handled by class_repr() in classobject.c. Excpt, on the other hand, is a type; i.e. its repr is handled by type_repr() in typeobject.c. (You can tell because class_repr() returns a value formatted as "" whereas type_repr returns a value formatted as "<%s '%s.%s'>", where the first %s gets filled with either "type" or "class".) This is looking more and more like a failure to abide by PEP 252/253. I think that the patch is simple, but I'm unusre of the ramifications. I also haven't looked at the 2.4 source to see how things used to work. Still, I think that I've got a work-around for OP's problem, I just need to test it under both 2.4 and 2.5. -- http://mail.python.org/mailman/listinfo/python-list
Re: Re-raising exceptions with modified message
On Jul 13, 12:45 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote: > samwyse wrote: > > TypeError: __class__ must be set to a class > > > Excpt ceratinly appears to be a class. Does anyone smarter than me > > know what's going on here? > > Not that I want to appear smarter, but I think the problem here is that > exceptions are new-style classes now, whereas Empty is an old-style > class. But even if you define Empty as a new-style class, it will not > work, you get: > > TypeError: __class__ assignment: only for heap types > > This tells us that we cannot change the attributes of a built-in > exception. If it would be possible, I simply would have overridden the > __str__ method of the original exception in the first place. > > -- Chris Chris, you owe me a beer if you're ever in St. Louis, or I'm ever in Germany. # - CUT HERE - # Written by Sam Denton <[EMAIL PROTECTED]> # You may use, copy, or distribute this work, # as long as you give credit to the original author. # tested successfully under Python 2.4.1, 2.4.3, 2.5.1 """ On Jul 5, 2007, at 8:53 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote: > What is the best way to re-raise any exception with a message > supplemented with additional information (e.g. line number in a > template)? Let's say for simplicity I just want to add "sorry" to > every exception message. Here is an example of typical usage: >>> def typical_usage(code): ... try: ... code() ... except Exception, e: ... simplicity = lambda self: str(e) + ", sorry!" ... raise modify_message(e, simplicity) Note that if we want to re-cycle the original exception's message, then we need our re-formatter (here called 'simplicity') to be defined inside the exception handler. I tried verious approaches to defining the re-formater, but all of them eventually needed a closure; I decided that I liked this approach best. This harness wraps the example so that doctest doesn't get upset. >>> def test_harness(code): ... try: ... typical_usage(code) ... except Exception, e: ... print "%s: %s" % (e.__class__.__name__, str(e)) Now for some test cases: >>> test_harness(lambda: 1/0) ZeroDivisionError: integer division or modulo by zero, sorry! >>> test_harness(lambda: unicode('\xe4')) UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128), sorry! """ def modify_message(old, f): """modify_message(exception, mutator) --> exception Modifies the string representation of an exception. """ class NewStyle(old.__class__): def __init__(self): pass NewStyle.__name__ = old.__class__.__name__ NewStyle.__str__ = f new = NewStyle() new.__dict__ = old.__dict__.copy() return new def _test(): import doctest return doctest.testmod(verbose=True) if __name__ == "__main__": _test() -- http://mail.python.org/mailman/listinfo/python-list
Re: Can a low-level programmer learn OOP?
On Jul 13, 1:05 pm, Chris Carlen <[EMAIL PROTECTED]> wrote: > John Nagle wrote: > > Chris Carlen wrote:[edit] > >> Hence, being a hardware designer rather than a computer scientist, I > >> am conditioned to think like a machine. I think this is the main > >> reason why OOP has always repelled me. > > > Why? > > When pointers were first explined to me, I went "Ok." And rather > quickly ideas lit up in my head about what I could do with them. > > When I read what OOP is, that doesn't happen. All I think is "what's > the point of this?" "What can this do for me that I can do already with > the procedural way of thinking?" And if it can't do anything new, then > why rearrange my thinking to a new terminology? It's results that > matter, not the paradigm. What can this do for me that I can do already with the procedural way of thinking? Absolutely nothing; it's all Turing machines under the hood. Why rearrange my thinking to a new terminology? Because new terminologies matter a lot. There's nothing that you can do with pointers that can't be done with arrays; I know because I wrote a lot of FORTRAN 77 code back in the day, and withouy pointers I had to write my own memory allocation routines that worked off of a really big array. Likewise, there's nothing that you can do in C that can't be done with C++ (especially since C++ was originally a preprocessor for C); however C++ will keep track of a lot of low-level detail for you so you don't have to think about it. Let's say that you have an embedded single-board computer with a serial and a parallel port. You probably have two different routines that you use to talk to them, and you have to always keep track which you are using at any given time. It's a lot easier to have a single CommPort virtual class that you use in all of your code, and then have two sub-classes, one for serial ports and one for parallel. You'll be especially happy for this when someone decides that as well as logging trace information to a printer, it would be nice to also log it to a technician's handhelp diagnostic device. -- http://mail.python.org/mailman/listinfo/python-list
Rats! vararg assignments don't work
I'm a relative newbie to Python, so please bear with me. After seeing how varargs work in parameter lists, like this: def func(x, *arglist): and this: x = func(1, *moreargs) I thought that I'd try this: first, *rest = arglist Needless to say, it didn't work. That leaves me with two questions. First, is there a good way to do this? For now, I'm using this: first, rest = arglist[0], arglist[1:] but it leaves a bad taste in my mouth. Second, is there any good reason why it shouldn't work? It seems like such an obvious idiom that I can't believe that I'm the first to come up with the idea. I don't really have the time right now to go source diving, so I can't tell if it would be wildly inefficient to implement. Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: Rats! vararg assignments don't work
Gary Herron wrote: > samwyse wrote: > >>I'm a relative newbie to Python, so please bear with me. After seeing >>how varargs work in parameter lists, like this: >> def func(x, *arglist): >>and this: >> x = func(1, *moreargs) >>I thought that I'd try this: >> first, *rest = arglist >>Needless to say, it didn't work. That leaves me with two questions. >> >>First, is there a good way to do this? For now, I'm using this: >> first, rest = arglist[0], arglist[1:] >>but it leaves a bad taste in my mouth. >> > > Well, your moreargs parameter is a tuple, and there are innumerable ways > to process a tuple. (And even more if you convert it to a list.) My use-case is (roughtly) this: first, *rest = f.readline().split() return dispatch_table{first}(*rest) -- http://mail.python.org/mailman/listinfo/python-list
Re: Rats! vararg assignments don't work
George Sakkis wrote: > On May 29, 11:33 pm, Matimus <[EMAIL PROTECTED]> wrote: > > >>Your attemtp: >> >>[code] >>first, rest = arglist[0], arglist[1:] >>[/code] >> >>Is the most obvious and probably the most accepted way to do what you >>are looking for. As for adding the fucntionality you first suggested, >>it isn't likely to be implemented. The first step would be to write a >>PEP though. > > > The time machine did it again: http://www.python.org/dev/peps/pep-3132/. Thanks! Now I just need to wait for Py3K and all of my problems will be solved. ;-) Actually, I'm surprised that the PEP does as much as it does. If tuples are implemented as S-expressions, then something like this: car, *cdr = tuple while leaving cdr a tuple would be trivial to implement. Of course, I'm an old-school LISPer, so what I consider surprising behavior doesn't always surprise anyone else, and vice versa. -- http://mail.python.org/mailman/listinfo/python-list
Python 2.5.1 can't find win32file?
I just upgraded from 2.4.something to 2.5.1. I get the stuff below. I tried easy-installing pywin32; same results. Anyone know what's going on? Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. Personal firewall software may warn about the connection IDLE makes to its subprocess using this computer's internal loopback interface. This connection is not visible on any external interface and no data is sent to or received from the Internet. IDLE 1.2.1 No Subprocess >>> import win32file Traceback (most recent call last): File "", line 1, in import win32file ImportError: DLL load failed: The specified module could not be found. >>> import sys >>> sys.path ['C:\\Documents and Settings\\dentos\\Desktop\\scripting', 'C:\ \Python25\\Lib\\idlelib', 'C:\\Python25\\lib\\site-packages\ \setuptools-0.6c6-py2.5.egg', 'C:\\Python25\\lib\\site-packages\ \sqlalchemy-0.3.10-py2.5.egg', 'C:\\Python25\\lib\\site-packages\ \pil-1.1.6-py2.5-win32.egg', 'C:\\Python25\\lib\\site-packages\ \epydoc-3.0beta1-py2.5-win32.egg', 'C:\\Python25\\lib\\site-packages\ \pywin32-210-py2.5-win32.egg', 'C:\\WINNT\\system32\\python25.zip', 'C: \\Python25\\DLLs', 'C:\\Python25\\lib', 'C:\\Python25\\lib\\plat-win', 'C:\\Python25\\lib\\lib-tk', 'C:\\Python25', 'C:\\Python25\\lib\\site- packages'] -- http://mail.python.org/mailman/listinfo/python-list
Re: How to programmatically insert pages into MDI.
On Jul 28, 7:46 am, fynali iladijas <[EMAIL PROTECTED]> wrote: > On Jul 24, 4:36 pm, fynali iladijas <[EMAIL PROTECTED]> wrote: > > > > > Hi, this query is regarding automating page insertions in Microsoft > > Document Imaging. > [...] > > > All help and advice will be most appreciated. > > > Thank you. > > > s|a fynali > > )-: > > -- > s|a fynali Perhaps you should post to a Microsoft-related newsgroup. This is the place for questions about the Python programming language, and the word "Python" didn't appear anywhere in your initial question. -- http://mail.python.org/mailman/listinfo/python-list
Re: Python 2.5.1 can't find win32file?
On Jul 28, 8:16 am, samwyse <[EMAIL PROTECTED]> wrote: > I just upgraded from 2.4.something to 2.5.1. I get the stuff below. > I tried easy-installing pywin32; same results. Anyone know what's > going on? > Interestingly enough, this works: C:\Python25>path=%path%;C:\Python25\Lib\site-packages\pywin32-210- py2.5-win32.eg g\pywin32_system32 C:\Python25>python Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import win32file >>> It looks like the system search path isn't getting updated so that PYWINTYPES25.DLL can be found when win32file.pyd is loaded. Anyone have any ideas? -- http://mail.python.org/mailman/listinfo/python-list
Re: Python 2.5.1 can't find win32file?
On Jul 28, 12:14 pm, Jay Loden <[EMAIL PROTECTED]> wrote: > samwyse wrote: > > Interestingly enough, this works: > > > C:\Python25>path=%path%;C:\Python25\Lib\site-packages\pywin32-210- > > py2.5-win32.eg > > g\pywin32_system32 > > > C:\Python25>python > > Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit > > (Intel)] on win32 > > Type "help", "copyright", "credits" or "license" for more information. > >>>> import win32file > > > It looks like the system search path isn't getting updated so that > > PYWINTYPES25.DLL can be found when win32file.pyd is loaded. > > > Anyone have any ideas? > > If you just want to update your PATH, you can do that from My Computer -> > Properties -> Advanced -> Environment Variables and just update PATH for your > user (or all users if you prefer). > > -Jay Well, I was hoping for something a bit more general. I'd've thought that anyone loading a DLL would set the Windows path beforehand, and that it would all be magically taken care of during the installation. For now, I'm putting this before my 'import' statement: os.environ['PATH'] += r';C:\Python25\Lib\site-packages\pywin32-210- py2.5-win32.egg\pywin32_system32' -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython before MainLoop
Chris Mellon wrote: > On 8/9/07, Heikki Toivonen <[EMAIL PROTECTED]> wrote: > >>[david] wrote: >> >>>I'd like to refresh the display before I start the main loop. If your window isn't able to interact with the user, then I'd consider it a splash screen, no matter if it does look exactly like your main application interface. >>We have this kind of situation in Chandler, where we display and update >>the splash screen before we enter MainLoop. >> [...] >>3. The splash screen refresh is basically: draw new stuff, >>self.Layout(), self.Update(), wx.Yield() >>http://lxr.osafoundation.org/source/chandler/application/Application.py#1421 Looking at the Chandler code suggests a solution to [david]'s original problem. It is possible that, on Windows only, he may need to call Update to finish painting the display. 1432 self.Layout() 1433 if wx.Platform == '__WXMSW__': 1434 self.Update() 1435 wx.GetApp().Yield(True) > wxYield spins the event loop in place. This can have some serious > consequences if you aren't very careful with your usage, like > recursively entering event handlers. I generally consider it an > experts only interface, and avoid it. I'll confess to being one of those old-school programmers who, back in the day, wrote his code around big select loops instead of using threads, but I'm intriged by the "experts only" designation. Can someone explain further? Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: clarification
Scott David Daniels wrote: > lefts = set() > rights = set() > with open('sheet1', 'r') as fh: > for line in fh: > trimmed = line.strip() > if trimmed: # Skip blanks (file end often looks like that) > left, right = line.strip().split('\t') > lefts.add(left) > rights.add(right) > result = lefts & rights > > -Scott # change to however many columns may later exist cols = [ set() for i in range(0, 2) ] with open('sheet1', 'r') as fh: for line in fh: for col, data in zip(cols, line.strip().split('\t')): col.add(data) result = cols[0] & cols[1] -- http://mail.python.org/mailman/listinfo/python-list
Re: unexpected optparse set_default/set_defaults behavior
[EMAIL PROTECTED] wrote: > Some rather unexpected behavior in the set_default/set_defaults > methods for OptionParser that I noticed recently: [...] > Why does set_default not raise an exception when passed a key that it > doesn't recognize? > > Bad typysts bewaer. > > The only reason I can think not to raise an exception is so that > defaults can be defined before the options are added. Is there some > use case that I'm not thinking of here? I realize that changing this > could break some existing scripts, but I'm still tempted to file this > as a bug. If you file it as a bug then I can assure you that you'll be told of a long list of use-cases that depend on that feature. -- http://mail.python.org/mailman/listinfo/python-list
Re: clarification
samwyse wrote: > Scott David Daniels wrote: > >> lefts = set() >> rights = set() >> with open('sheet1', 'r') as fh: >> for line in fh: >> trimmed = line.strip() >> if trimmed: # Skip blanks (file end often looks like that) >> left, right = line.strip().split('\t') >> lefts.add(left) >> rights.add(right) >> result = lefts & rights >> >> -Scott > > > # change to however many columns may later exist > cols = [ set() for i in range(0, 2) ] > with open('sheet1', 'r') as fh: > for line in fh: > for col, data in zip(cols, line.strip().split('\t')): > col.add(data) > result = cols[0] & cols[1] My laptop started complaining about low power before I was really finished with this last night, so I just hit Send and went to bed. The last line really should be: result = reduce(operator.and_, cols) I'll note that using 'zip' transparently deals with handling those cases where there are either more or fewer columns of data than expected. Finally, does anyone familar with P3K know how best to do the reduction without using 'reduce'? Right now, sets don't support the 'add' and 'multiply' operators, so 'sum' and (the currently ficticious) 'product' won't work at all; while 'any' and 'all' don't work as one might hope. Are there an 'intersection' and 'union' built-ins anywhere? -- http://mail.python.org/mailman/listinfo/python-list
Re: clarification
Alex Martelli wrote: > Of course, hoisting the unbound method out of the loops can afford the > usual small optimization. But my point is that, in Python, these > operations (like, say, the concatenation of a sequence of lists, etc) > are best performed "in place" via loops calling mutator methods such as > update and intersection_update (or a list's extend, etc), rather than > "functionally" (building and tossing away many intermediate results). > E.g., consider: > > brain:~ alex$ python -mtimeit -s'sos=[set(range(x,x+4)) for x in > range(0, 100, 3)]' 'r=set()' 'for x in sos: r.update(x)' > 10 loops, best of 3: 18.8 usec per loop > > brain:~ alex$ python -mtimeit -s'sos=[set(range(x,x+4)) for x in > range(0, 100, 3)]' 'r=reduce(set.union, sos, set())' > 1 loops, best of 3: 87.2 usec per loop > > Even in a case as tiny as this one, "reduce" is taking over 4 times > longer than the loop with the in-place mutator -- and it only gets > worse, as we're talking about O(N squared) vs O(N) performance! Indeed, > this is part of what makes reduce an "attractive nuisance"...;-). [[And > so is sum, if used OTHERWISE than for the documented purpose, computing > "the sum of a sequence of numbers": a loop with r.extend is similarly > faster, to concatenate a sequence of lists, when compared to sum(sol, > [])...!!!]] Curiously, when I attempt the actual problem at hand (set intersection) rather than something altogether different (set union) on my Dell laptop running Win2K Pro, I get the following results: stmt = 'r=reduce(set.intersection, los)' best of 3: 21.9 usec per loop stmt = 'r=intersect_all(los)' best of 3: 29.3 usec per loop So, the "nuisance" is more attractive than you thought. Apparently, one can't really depend on "in place" mutator methods being more efficient that using functional techniques. BTW, the above figures reflect 10,000 iterations; using larger counts makes the difference even larger. I suspect that this is because the Python interpreter has fewer chances to be interrupted by external processes when it's using 'reduce'. This in turn indicates that both implementations actually work about same and your "O(n squared)" argument is irrelevant. P.S. Here's the source I used for the timings: from timeit import Timer setup = """ def intersect_all(los): it = iter(los) result = set(it.next()) for s in it: result.intersection_update(s) return result not7=range(2,11) not7.remove(7) los=[set(range(0,360,step)) for step in not7] """ number = 1 repeat = 3 precision = 3 for stmt in 'r=reduce(set.intersection, los)', 'r=intersect_all(los)': t = Timer(stmt, setup) r = t.repeat(repeat, number) best = min(r) usec = best * 1e6 / number print "stmt =", repr(stmt) print "best of %d: %.*g usec per loop" % (repeat, precision, usec) -- http://mail.python.org/mailman/listinfo/python-list
Re: Symbolic Link
mosscliffe wrote: > I am trying to create a link to a file, which I can then use in an > HTML page. > > The system is Linux on a hosted web service, running python 2.3. > Other than that I have no knowledge of the system. > > The link is created OK, but when I try to use it as filename for the > IMG TAG, it does not get displayed. The page source of the created > page is pointing to the link as temp/test1.jpg What are you trying to do that you can't use the original file instead of creating a link? There might be a way to side-step the entire problem. -- http://mail.python.org/mailman/listinfo/python-list
Re: Parser Generator?
Jack wrote: > Thanks for all the replies! > > SPARK looks promising. Its doc doesn't say if it handles unicode > (CJK in particular) encoding though. > > Yapps also looks powerful: http://theory.stanford.edu/~amitp/yapps/ > > There's also PyGgy http://lava.net/~newsham/pyggy/ > > I may also give Antlr a try. > > If anyone has experiences using any of the parser generators with CJK > languages, I'd be very interested in hearing that. I'm going to echo Tommy's reply. If you want to parse natural language, conventional parsers are going to be worse than useless (because you'll keep thinking, "Just one more tweak and this time it'll work for sure!"). Instead, go look at what the interactive fiction community uses. They analyse the statement in multiple passes, first picking out the verbs, then the noun phrases. Some of their parsers can do on-the-fly domain-specific spelling correction, etc, and all of them can ask the user for clarification. (I'm currently cobbling together something similar for pre-teen users.) -- http://mail.python.org/mailman/listinfo/python-list
Re: Searching for pixel color
michael maver wrote: > Hello, I was just wondering if anyone knew of a way to search the screen > for a certain color in Python. I know of lots of ways to do this... > I know it is possible to do this in other languages, but I'm not sure > how I'd go about doing this in Python. Just to let you know, I'm running > windows XP and I don't really need it to be a cross platform solution, > but if it was that'd be an extra bonus. ... but they are all platform dependent; not just Windows vs Unix, but PIL vs wxWin vs whatever. def search_screen(desired_color): root = my_gui.root_window() width, height = root.get_size() for x in xrange(0, width): for y in xrange(0, height): if root.get_pixel(x,y) == desired_color: return x,y return -1, -1 Modify the above using the appropriate values for 'my_gui' and its methods, 'root_window', 'get_size' and 'get_pixel'. > Thanks very much for taking the time to read this and, hopefully, respond! You're welcome. -- http://mail.python.org/mailman/listinfo/python-list
Re: 1)URL QueryString Parsing 2)Search Engine Spiders
mosscliffe wrote: > I am trying to create a back link, equivalent to the browser back > action and I can not use java script. The target user does not allow > java script. > > I am using HTTP_REFERER. > > I need to add the original Query String values. > > Is there a way to get the QueryString element other than by using > cgi.FieldStorage, as I just want to return with the values that were > current in the calling page. > > gv.orgQueryString = "" > > gv.BackButton = ' gv.orgQueryString + '">BACK' I'm not sure I understand your problem. Does the above code not work? > Am I right in thinking Search Engine Spiders will never see my script > pages as they exist only for the duration of the python script's > execution ? And even then as they are xxx.py, they would not be > seen. Anyone who accesses your web server will see the pages that you serve. If you serve the xxx.py files, then they can be seen and indexed, otherwise they are invisible. -- http://mail.python.org/mailman/listinfo/python-list
Re: Development for dual core machine
Andy wrote: > Hi guys, > > I'm sorry, I'm not sure this is the correct group to be asking this > kind of question... > > I'm going to develop a software package that includes a web server > (and PHP code) , a database, and some Python code of course. I am > being strongly suggested to make it to work on a dual- or multi-core > computer, but I'm confused on how to take advantage of the multiple > CPUs. > >>From what I read, I think that simply by making the package run in > several separate processes (web server, database server, Python > interpreter, etc.), and/or using multiple threads (which I will > anyway) the package should be able to use multiple CPUs. > > Is my understanding correct? So actually, all I have to do is just > write my multi-threaded Python code as usual? And how is it decided > which process and which threads go to CPU 1, CPU 2, etc.? Perhaps the > BIOS? > > Any advice greatly appreciated. > Andy > The Python interpreter is not multi-cpu aware, so using Python threads won't work on multiple CPUs. If your tasks are CPU-bound, then fork multiple processes. Most web servers (Apache) can handle this automatically for you. -- http://mail.python.org/mailman/listinfo/python-list
Re: Symbolic Link
mosscliffe wrote: > On 22 Aug, 00:05, Ian Clark <[EMAIL PROTECTED]> wrote: >> >>>On Aug 19, 4:29 pm,mosscliffe<[EMAIL PROTECTED]> wrote: >>> The source file is in an area which python can see, but not the browser. I am trying to make a link in a browser friendly area so I can use it to display an image file. >> >>My question would be why a symbolic link? Why not a hard link? Are the >>two directories on different mount points? After the script finishes >>does python need to see that image file again? Why not just move it? > > I have tested a hard link now and it seems to work fine. I am > deleting the link/s at the end of the session/s. This is a bit late, but the reason the symbolic link won't work is because it's the web-server that's resolving it. The browser can only see things that the web-server, huh, serves, so what was meant in the first paragraph above was that the web server couldn't access the file in its original location. If you create a sym-link, the web server opens the link, finds out the actual location of the file, and tries to open that file, which it still can't do. A hard-link, OTOH, allows direct access to the contents of a file, as long as it is on the same filesystem. No extra steps are required, so the process runs a few microseconds faster, and directory-level permissions can't get in the way. -- http://mail.python.org/mailman/listinfo/python-list
Re: Symbolic Link
On Sep 9, 10:05 pm, Lawrence D'Oliveiro <[EMAIL PROTECTED] central.gen.new_zealand> wrote: > In message <[EMAIL PROTECTED]>,samwysewrote: > > > A hard-link, OTOH, allows > > direct access to the contents of a file, as long as it is on the same > > filesystem. No extra steps are required, so the process runs a few > > microseconds faster, and directory-level permissions can't get in the way. > > Hard links are best avoided, because of the confusion they can cause. There are reasons to use hard links, there are reasons to use symbolic links. Depending on the circumstances, either could "cause confusion" simply because either could do something other than what's needed. Here's a handy chart to help decide which is appropriate: http://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/ifs/rzaaxmstlinkcmp.htm -- http://mail.python.org/mailman/listinfo/python-list
BaseHTTPServer issues
I've just now submitted two issues to the issue tracker: 1491BaseHTTPServer incorrectly implements response code 100 RFC 2616 sec 8.2.3 states, "An origin server that sends a 100 (Continue) response MUST ultimately send a final status code, once the request body is received and processed, unless it terminates the transport connection prematurely." The obvious way to do this is to invoke the 'send_response' method twice, once with a code of 100, then with the final code. However, BaseHTTPServer will always send two headers ('Server' and 'Date') when it send a response. One possible fix is to add an option to the method to suppress sending headers; another is to add the following code to the 'send_response' method, immediately prior to the calls to 'self.send_header': if code == 100: return The more paranoid among us may wish to use this code instead: if code == 100: expectation = self.headers.get('Expect', "") if expectation.lower() == '100-continue': return 1492BaseHTTPServer hard-codes Content-Type for error messages The send_error method always sends a Content-Type of 'text/html'. Other content types are both possible and desirable. For example, someone writing a REST server might wish to send XML error messages. Following the example of DEFAULT_ERROR_MESSAGE, I propose adding the following in the appropriate places: 91a92,94 > # Default error content-type > DEFAULT_ERROR_TYPE = 'text/html' > 345c348 < self.send_header("Content-Type", "text/html") --- > self.send_header("Content-Type", error_message_type) 351a355 > error_message_type = DEFAULT_ERROR_TYPE -- http://mail.python.org/mailman/listinfo/python-list
Re: the annoying, verbose self
On Nov 23, 7:16 pm, "Patrick Mullen" <[EMAIL PROTECTED]> wrote: > Most of the time self doesn't bother me in the slightest. The one > time it does bother me however, is when I am turning a function into a > method. In this case, often I have many local variables which I > actually want to be instance variables, so I have to add self to all > of them. Of course, this is going to cause me some grief no matter > which language I am using. If it was enough trouble, it wouldn't be > hard to make a filter that converts my code automatically. I've had the same thought, along with another. You see, on of my pet peeves about all OO languages that that when creating new code, I generally begin by writing something like this: cat = 'felix' dog = 'rover' def example(): global cat, dog # not always required, but frequently needed return ', '.join((cat, dog)) Later, I inevitably decide to encapsulate it inside a class, which means lots of source changes to change my function into a method: class my_pets: cat = 'felix' dog = 'rover' def example(self): return ', '.join((self.cat, self.dog)) My idea is to introduce syntax that treats top-level functions as methods of a global, anonymous, class: cat = 'felix' dog = 'rover' def example(): return ', '.join((.cat, .dog)) (btw, we'll also stop auto-magically recognizing global variables inside functions, forcing the use of the '.' in global names.) Thus, to convert the above into a class, we just need to add one line and alter the indentation: class my_pets: cat = 'felix' dog = 'rover' def example(): # anonymous 'self' is implicit inside class defs. return ', '.join((.cat, .dog)) You'd need someway to refer to higher lexical levels, possibly by chaining periods; this would break ellipsis but that could be replaced by a keyword such as 'to'. And you'd probably want to keep 'global', but as a keyword for those rare cases where you need to force a reference to the outer-most lexical level: warming = 42 def generator(factiod): def decorator(func): def wrapper(*args, **kwds): if ..factoid == None: return .func(*args, **kwds) else: return ..factoid + global.warming return wrapper return decorator -- http://mail.python.org/mailman/listinfo/python-list
setting attributes on external types (was Re: eof)
On Nov 23, 2:06 am, greg <[EMAIL PROTECTED]> wrote: > There's a fair amount of overhead associated with providing > the ability to set arbitrary attributes on an object, which > is almost never wanted for built-in types, so it's not > provided by default. > > You can easily get it if you want it by defining a Python > subclass of the type concerned. Speaking of which, I've got a big file: >>> input = open('LoTR.iso') I'd like to get the md5 hash of the file: >>> import md5 >>> m = md5.new() I've also got this nifty standard module which will allow me, among other things, to copy an arbitrary file: >>> import shutil I'd like to say copy the file to my object, but it doesn't quite work: >>> shutil.copyfileobj(input, m) Traceback (most recent call last): File "", line 1, in shutil.copyfileobj(source, m) File "C:\Python25\lib\shutil.py", line 24, in copyfileobj fdst.write(buf) AttributeError: '_hashlib.HASH' object has no attribute 'write' No problem, I'll just add an attribute: >>> setattr(m, 'write', m.update) Traceback (most recent call last): File "", line 1, in setattr(m, 'write', m.update) AttributeError: '_hashlib.HASH' object has no attribute 'write' Anyone have an example of how to efficiently do this? Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: the annoying, verbose self
On Nov 24, 4:07 am, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote: > On Sat, 24 Nov 2007 01:55:38 -0800, samwyse wrote: > > I've had the same thought, along with another. You see, on of my pet > > peeves about all OO languages that that when creating new code, I > > generally begin by writing something like this: > > > cat = 'felix' > > dog = 'rover' > > def example(): > > global cat, dog # not always required, but frequently needed > > return ', '.join((cat, dog)) > > Ouch that's bad design IMHO. The need to use ``global`` is a design > smell, if needed *frequently* it starts to stink. I'm not sure what you mean. In the example that I gave, the 'global' statement isn't needed. However, here's a different example: >>> top_score = 0 >>> def leaderboard(my_score): if my_score > top_score: print "A new high score!" top_score = myscore print "Top score:", top_score Traceback (most recent call last): File "", line 1, in leaderboard(7, 'samwyse') File "", line 2, in leaderboard if my_score > top_score: UnboundLocalError: local variable 'top_score' referenced before assignment -- http://mail.python.org/mailman/listinfo/python-list
Re: How can I create customized classes that have similar properties as 'str'?
On Nov 24, 5:44 am, Licheng Fang <[EMAIL PROTECTED]> wrote: > Yes, millions. In my natural language processing tasks, I almost > always need to define patterns, identify their occurrences in a huge > data, and count them. [...] So I end up with unnecessary > duplicates of keys. And this can be a great waste of memory with huge > input data. create a hash that maps your keys to themselves, then use the values of that hash as your keys. >>> store = {} >>> def atom(str): global store if str not in store: store[str] = str return store[str] >>> a='this is confusing' >>> b='this is confusing' >>> a == b True >>> a is b False >>> atom(a) is atom(b) True -- http://mail.python.org/mailman/listinfo/python-list
Re: the annoying, verbose self
On Nov 24, 7:50 am, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote: > On Sat, 24 Nov 2007 02:54:27 -0800, samwyse wrote: > > On Nov 24, 4:07 am, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote: > >> On Sat, 24 Nov 2007 01:55:38 -0800, samwyse wrote: > >> > I've had the same thought, along with another. You see, on of my pet > >> > peeves about all OO languages that that when creating new code, I > >> > generally begin by writing something like this: > > >> > cat = 'felix' > >> > dog = 'rover' > >> > def example(): > >> > global cat, dog # not always required, but frequently needed > >> > return ', '.join((cat, dog)) > > >> Ouch that's bad design IMHO. The need to use ``global`` is a design > >> smell, if needed *frequently* it starts to stink. > > > I'm not sure what you mean. In the example that I gave, the 'global' > > statement isn't needed. However, here's a different example: > > I mean that global names that are (re)bound from within functions couple > these functions in a non-obvious way and make the code and data flow harder > to follow and understand. Also it makes refactoring and testing more > difficult because of the dependencies. The whole point of this sub-thread is the difficulty of turning global vars and functions into class vars and functions, and that is something that is usually done precisely because the code and data flow has become harder to follow and understand. -- http://mail.python.org/mailman/listinfo/python-list
Re: the annoying, verbose self
On Nov 24, 10:07 am, Duncan Booth <[EMAIL PROTECTED]> wrote: > Ton van Vliet <[EMAIL PROTECTED]> wrote: > > > It would boil down to choice: explicit/speed vs implicit/readability > > No, it would boil down to explicit+speed+readability+maintainability vs > implicit+error prone. > > It would mean that as well as the interpreter having to search the > instance to work out whether each name referenced an attribute or a global > the reader would also have to perform the same search. It would mean that > adding a new attribute to an instance would change the meaning of the > methods which is a recipe for disaster. Besides Pascal, Visual Basic also offers a 'with' statement that behaves almost in this way. That in itself should be an indication that the whole thing is a bad idea. ;-) The way it works, however, is that you do have to prefix members with a '.' and the interpreter tries to bind with each nested 'with' variable in turn. It's tolerable with one 'with' statment, but once you start nesting them it becomes dangerous. My idea in a parallel thread is to treat a '.' prefix like '../' in file paths; each one moves you up a level in the symbol table. In a top-level function, it means a global name; in a class method it means a member. The @classmethod and @staticmethod decorators would need to fix things so that '.' refers to the appropriate things. There's no reason why a 'using' statement couldn't perform nesting as well: '.' refers to the 'using' variable, '..' refers to what '.' previously referred to, etc. OTOH, the point of 'using' is to reduce typing, so you might instead add 'as' clauses as an alternate way to reduce confusion: >>> using myclass.new() as p: p.do_something() p.something_else() Of course, now its starting to look more like a Python 'with' statement, and I think there's a way to do basically this already. -- http://mail.python.org/mailman/listinfo/python-list
Re: How can I create customized classes that have similar properties as 'str'?
On Nov 24, 10:35 am, Licheng Fang <[EMAIL PROTECTED]> wrote: > Thanks. Then, is there a way to make python treat all strings this > way, or any other kind of immutable objects? The word generally used is 'atom' when referring to strings that are set up such that 'a == b' implies 'a is b'. This is usually an expensive process, since you don't want to do it to strings that are, e.g., read from a file. Yes, it could be done only for string constants, and some languages (starting with LISP) do this, but that isn't what you (or most people) want. Whether you realize it or not, you want control over the process; in your example, you don't want to do it for the lines read from your file, just the trigrams. The example that I gave does exactly that. It adds a fixed amount of storage for each string that you 'intern' (the usual name given to the process of generating such a string. Let's look at my code again: >>> store = {} >>> def atom(str): global store if str not in store: store[str] = str return store[str] Each string passed to 'atom' already exists. We look to see if copy already exists; if so we can discard the latest instance and use that copy henceforth. If a copy does not exist, we save the string inside 'store'. Since the string already exists, we're just increasing its reference count by two (so it won't be reference counted) and increasing the size of 'store' by (an amortized) pair of pointers to that same string. -- http://mail.python.org/mailman/listinfo/python-list
Re: How can I create customized classes that have similar properties as 'str'?
On Nov 24, 5:44 am, Licheng Fang <[EMAIL PROTECTED]> wrote: > Yes, millions. In my natural language processing tasks, I almost > always need to define patterns, identify their occurrences in a huge > data, and count them. Say, I have a big text file, consisting of > millions of words, and I want to count the frequency of trigrams: > > trigrams([1,2,3,4,5]) == [(1,2,3),(2,3,4),(3,4,5)] BTW, if the components of your trigrams are never larger than a byte, then encode the tuples as integers and don't worry about pointer comparisons. >>> def encode(s): return (ord(s[0])*256+ord(s[1]))*256+ord(s[2]) >>> def trigram(s): return [ encode(s[i:i+3]) for i in range(0, len(s)-2)] >>> trigram('abcde') [6382179, 6447972, 6513765] -- http://mail.python.org/mailman/listinfo/python-list
Re: the annoying, verbose self
On Nov 24, 1:10 pm, "Patrick Mullen" <[EMAIL PROTECTED]> wrote: > If there were a "using" or if the with statement would handle > something like this, I wouldn't use it. "s." is only 2 characters. I > saw chained dots mentioned. Chained dots are 2 characters. Why are > we still discussing this? "s." is the answer, or pulling the > attributes into local vars if you are going to use them many times, to > save lookup. This is not a band-aid, this is an actual valid > programming technique. There is more to programming than typing... Actually, the chained dots are solving a completely different problem, that of refactoring a collection of functions that use global vars into a class. Although I'm now wondering if I could jigger something together using globals() to make a top-level self-like object. Hmmm, maybe someting like this: >>> class GlobalSelf(object): def __init__(self): self.__dict__ = globals() >>> x = 42 >>> def myfunc(*args): "something that I may want to refactor later" s = GlobalSelf() s.x += 1 >>> x 42 >>> myfunc() >>> x 43 -- http://mail.python.org/mailman/listinfo/python-list
__iadd__ useless in sub-classed int
For whatever reason, I need an inproved integer. Sounds easy, let's just subclass int: >>> class test(int): pass Now let's test it: >>> zed=test(0) >>> zed.__class__ >>> zed 0 So far, so good. Now let's try incrementing: >>> zed+=1 >>> zed 1 >>> zed.__class__ WTF??! Is this a bug or is it the inevitable result of optimizing for the case where all integers are indistinguishable? -- http://mail.python.org/mailman/listinfo/python-list
Re: How can I create customized classes that have similar properties as 'str'?
On Nov 24, 6:38 pm, Hrvoje Niksic <[EMAIL PROTECTED]> wrote: > samwyse <[EMAIL PROTECTED]> writes: > > create a hash that maps your keys to themselves, then use the values > > of that hash as your keys. > > The "atom" function you describe already exists under the name > "intern". D'oh! That's what I get for not memorizing "Non-essential Built-in Functions". In my defense, however, my function will work with anything that can be used as a dictionary key (strings, tuples, frozen sets, etc), not just character strings; thus we return to the original: >>> a=(1,2,3) >>> b=(1,1+1,1+1+1) >>> a == b True >>> a is b False >>> atom(a) is atom(b) True >>> intern(a) is intern(b) Traceback (most recent call last): File "", line 1, in ? intern(a) is intern(b) TypeError: intern() argument 1 must be string, not tuple -- http://mail.python.org/mailman/listinfo/python-list
Re: __iadd__ useless in sub-classed int
On Dec 6, 1:12 pm, "Diez B. Roggisch" <[EMAIL PROTECTED]> wrote: > samwyse schrieb: > > > For whatever reason, I need an inproved integer. Sounds easy, let's > > just subclass int: > > >>>> class test(int): > >pass > > > Now let's test it: > > >>>> zed=test(0) > >>>> zed.__class__ > > > >>>> zed > > 0 > > > So far, so good. Now let's try incrementing: > > >>>> zed+=1 > >>>> zed > > 1 > >>>> zed.__class__ > > > > > WTF??! > > Is this a bug or is it the inevitable result of optimizing for the > > case where all integers are indistinguishable? > > There has been a lengthe thread over the semantics of __iadd__ a few > weeks ago. It _can_ modify the object in question in-place (something > not possible for ints anyway), but it will ALWAYS return a reference > which will be set to the left-hand-side. Thanks! I'd missed that thread, googling found it but it didn't look noteworthy at first glance. I've not yet read the entire thread, but I did see a reference to PEP 203. )So, given the expression: ) ) x += y ) )The object `x' is loaded, then `y' is added to it, and the )resulting object is stored back in the original place. That agrees with what I'm seeing, all right. The problem is, the resulting object has a different type, which seems to violate the spirit of a later paragraph: )Writing the above expression as ) ) = ) )is both more readable and less error prone, because it is )instantly obvious to the reader that it is that is being )changed, and not that is being replaced by something almost, )but not quite, entirely unlike . And that's my complaint. The value in is being replaced by something almost, but not quite, identical to the original value. Python's internal implementation of __iadd__ for isn't returning , it's returning a new value belonging to the super-class. My whole point is overloading was that I'd hoped to avoid having to write a bunch of methods to perform in-place modifications. Looks like I stuck, however. -- http://mail.python.org/mailman/listinfo/python-list
Re: Terminology: "script" versus "program"
Ben Finney wrote: > George Sakkis <[EMAIL PROTECTED]> writes: > > >>On Jan 23, 8:14 pm, [EMAIL PROTECTED] wrote: >> >>>The annual Linux Journal survey is online now for any Linux users >>>who want to vote for Python. >>>http://www.linuxjournal.com/node/1006101 >> >>... >>18. What is your favorite programming language? >>(15 choices, Python not included) >> >>19. What is your favorite scripting language? >>o Python >>o Perl >>(5 more choices) >> >>Python is much more than a "scripting language" (whatever this >>means, other than a semi-derogatory term used by clueless PHBs). >>Sorry, I'll pass. > > > I agree entirely. > > The term "script" has the strong connotation of a limited-purpose > program designed to solve a problem expressed almost entirely as a > simple series of steps. Languages that are often used to write such > scripts are usually referred to as "scripting languages", which > becomes a denigration because such a language need not have support > for much else. I strongly disagree with your interpretation. Scritping languages provide high-level facilites for process control. Historically, they were purely interpretive but now they tend to compile to some sort of byte code. Examples include the various shells, Rexx, and various languages whose names start with "P". Languages which only express a "series of steps" are generally called batch languages. I've never heard anyone refer to a .BAT file as a script. In scripting languages, speed of execution is often less important than speed of implementation. When speed of execution is important, it is easier to invoke an external module than to patch or rewrite the interpreter. In Python, PERL and BASH, these modules can be dynamically linked libraries as well as stand-alone executables. Finally, the provided process control facilities are often generalized into quite powerful support for "programming in the large", especially both object-oriented and functional programming. This leads to supprot for a much broader set of practices and solutions than any mere programming language can easily provide. The only drawback I've ever found to this is that it's easy to accidentally use huge amounts of memory, for instance by 'slurping' files into memory in a single command. > This term seems quite prevalent among the Python core developers, > unfortunately. The 'distutils' module even has the term 'script' used > in its interface, to refer to the programs that are to be distributed. Apparently the core developers agree with my interpretation, not yours. -- http://mail.python.org/mailman/listinfo/python-list
Re: Python noob SOS (any [former?] Perlheads out there?)
kj wrote: > I'd written a Perl module to facilitate the writing of scripts. > It contained all my boilerplate code for parsing and validating > command-line options, generating of accessor functions for these > options, printing of the help message and of the full documentation, > testing, etc. A lot of people seem to have gotten hung up on this paragraph. kj remarks in one reply that he *does* use optparse, but there still seems to be much confusion. I've long done something similar, so I'll attempt to clarify. For most of the programming languages that I use, my first exercise is to write a program that accepts a 'getopt' string and creates a program around it. Here's a simple version that I just whipped out; the version that I commonly use is a bit more complicated. """%s [-h] [optionstring] The program generates boilerplate for a Python script. It accepts a single argument consisting of a string of option letters that you wish the script to recognize, with options that require an argument followed by a colon (i.e., the same format that Unix getopt() uses). Written by samwyse Created on Feb 02, 2008 """ import sys import getopt class UserError(Exception): def __init__(self, msg): self.msg = msg class Usage(UserError): pass def main(argv=None): if argv is None: argv = sys.argv # parse command line options try: try: opts, args = getopt.getopt(argv[1:], "h") except getopt.error, msg: raise Usage(msg) # process options for o, a in opts: if o == '-h': print __doc__ % argv[0] return 0 except UserError, err: print >>sys.stderr, err.msg print >>sys.stderr, "for help use --help" if type(err) is Usage: return 2 else: return 1 # process arguments for arg in args: # process() is defined elsewhere process(arg) ####### def process(shortopts): from time import strftime prolog = '''\ """Module docstring. This serves as a long usage message. Written by %(author)s Created on %(date)s """ import sys import getopt class UserError(Exception): def __init__(self, msg): self.msg = msg class Usage(UserError): pass def main(argv=None): if argv is None: argv = sys.argv # parse command line options try: try: opts, args = getopt.getopt(argv[1:], "%(opts)s") except getopt.error, msg: raise Usage(msg) # process options for o, a in opts:''' has_arg = '''\ if o == '-%(opt)s': opt_%(opt)s = a''' no_arg = '''\ if o == '-%(opt)s': opt_%(opt)s = True''' epilog = '''\ except UserError, err: print >>sys.stderr, err.msg print >>sys.stderr, "for help use --help" if type(err) is Usage: return 2 else: return 1 # process arguments for arg in args: # process() is defined elsewhere process(arg) if __name__ == "__main__": sys.exit(main()) ''' values = { 'date': strftime('%b %d, %Y'), 'author': 'samwyse', 'opts': shortopts } print prolog % values for i in range(len(shortopts)): c = shortopts[i] if c != ':': if shortopts.startswith(':', i+1): print has_arg % { 'opt': c } else: print no_arg % { 'opt': c } print epilog % values ####### if __name__ == "__main__": sys.exit(main()) -- http://mail.python.org/mailman/listinfo/python-list
Re: Does anyone else use this little idiom?
[EMAIL PROTECTED] wrote: > My apologies if any attributions are messed up. > > On Feb 3, 1:28 am, Steven D'Aprano <[EMAIL PROTECTED] > cybersource.com.au> wrote: > >>If you want an explicit name, try a variation of "dontcare". Assuming >>that you're an English speaker. I'm with Steven here. I typically use 'dontcare' or 'ignore', or occasionally 'asdf'. I also tend to use variables whose name-length is proportional to the size of their scope. > I'd really > prefer something like the Ruby syntax because all you have to write is > the number of times you want to do something, and then the thing you > want to do. (I guess, in that respect, I'd even consider the xrange > call a redundancy.) I'd like to see a '..' operator that does what 'xrange' does, but I'm not going to hold my breath. -- http://mail.python.org/mailman/listinfo/python-list
Re: sharing/swapping items between lists
On Apr 14, 7:01 pm, Aaron Brady wrote: > Here is an idea. Create a list of all possible pairs, using > itertools.combinations. You'll notice everyone gets equal play time > and equal time against each other on a pair-by-pair basis. Then, call > random.shuffle until one player isn't playing on two courts in one > day. > > It has the disadvantage that you might end up with player A playing > lots early on and rarely at the end, and B rarely early on and lots at > the end. Perhaps you could generate a few to several correct > solutions, then choose the most evenly distributed. Does this make > sense? Here's my idea: generate all possible pairs: >>> import itertools >>> players = [chr(c) for c in xrange(ord('a'),ord('z')+1)] >>> all_pairs = list(itertools.combinations(players,2)) partition the list: >>> def choose_nonoverlapping(pairs): chosen, leftover, used = list(), list(), list() for p in pairs: a, b = p if a in used or b in used: leftover.append(p) else: chosen.append(p) used.append(a) used.append(b) return chosen, leftover >>> court_count = 10 >>> week_count = 10 >>> pairs = all_pairs >>> for week in xrange(week_count): print 'week', week+1 this_week, pairs = choose_nonoverlapping(pairs) print ', '.join(map(lambda t: ' vs '.join(t), this_week [:court_count])) pairs[0:0] = this_week[court_count:] week 1 a vs b, c vs d, e vs f, g vs h, i vs j, k vs l, m vs n, o vs p, q vs r, s vs t week 2 u vs v, w vs x, y vs z, a vs c, b vs d, e vs g, f vs h, i vs k, j vs l, m vs o week 3 n vs p, q vs s, r vs t, a vs d, b vs c, e vs h, f vs g, i vs l, j vs k, m vs u week 4 o vs v, w vs y, x vs z, a vs e, b vs f, c vs g, d vs h, i vs m, j vs n, k vs p week 5 l vs q, r vs s, t vs u, a vs f, b vs e, c vs h, d vs g, i vs n, j vs m, k vs o week 6 p vs v, w vs z, x vs y, a vs g, b vs h, c vs e, d vs f, i vs o, j vs q, k vs m week 7 l vs n, r vs u, a vs h, b vs g, c vs f, d vs e, i vs p, j vs o, k vs q, m vs s week 8 t vs v, a vs i, b vs j, c vs k, d vs l, e vs m, f vs n, g vs o, h vs p, q vs u week 9 r vs w, s vs x, a vs j, b vs i, c vs l, d vs k, e vs n, f vs m, g vs p, h vs o week 10 q vs t, u vs y, v vs z, a vs k, b vs l, c vs i, d vs j, e vs o, f vs p, g vs m -- http://mail.python.org/mailman/listinfo/python-list
Re: sharing/swapping items between lists
On Apr 15, 8:13 am, Aaron Brady wrote: > On Apr 15, 6:57 am, samwyse wrote: > > > Here's my idea: generate all possible pairs: > > > >>> import itertools > > >>> players = [chr(c) for c in xrange(ord('a'),ord('z')+1)] > > >>> all_pairs = list(itertools.combinations(players,2)) > > > partition the list: > > >>> def choose_nonoverlapping(pairs): > > chosen, leftover, used = list(), list(), list() > > for p in pairs: > > a, b = p > > if a in used or b in used: > > leftover.append(p) > > else: > > chosen.append(p) > > used.append(a) > > used.append(b) > > return chosen, leftover > > > >>> court_count = 10 > > >>> week_count = 10 > > >>> pairs = all_pairs > > >>> for week in xrange(week_count): > > print 'week', week+1 > > this_week, pairs = choose_nonoverlapping(pairs) > > print ', '.join(map(lambda t: ' vs '.join(t), this_week > > [:court_count])) > > pairs[0:0] = this_week[court_count:] > > snip > > Your idea arrives at a sub-optimal solution on players= 'abcdef', > court_count= 3. > > Correct, by hand (5 weeks): > > ab cd ef > ac be df > ad ce bf > ae bd cf > af bc de > > Program (7 weeks): > [snip] > > However, you do correctly arrive at all the combinations, in better > than the naive 'one pair per week' solution. Further, you produced > the correct solution for players= 'abcdef', for court_count= 1 and > court_count= 2, which I also tested. Damage report? It does work better when there are a limited number of courts, but since that was in the original description, I didn't worry too much. One could product several random shuffles of the list of combinations and see which produced the shortest list of results. That would add indeterminancy without guaranteeing an optimal result. But I think that other people have algorithms for that case, so I'm not too worried. I've tried generalizing to competitions with more than two player (e.g. the Pinewood Derby, where up four cars are in each heat), but the algorithm falls apart, mostly due to the way itertools.combinations returns its results. -- http://mail.python.org/mailman/listinfo/python-list
Re: sharing/swapping items between lists
On Apr 15, 8:56 am, Aaron Brady wrote: > > The randomizing solution isn't quite suitable for 16 teams. With 5 > teams/1 court, and 5 teams/2 courts, 6 teams/2 courts, the solution > comes within seconds. For 7 teams/3 courts, the solution takes a few > minutes. 7 teams/3 courts is the same as 8 teams/4 courts, where the extra player is named "bye". In other words, it's an uncontrained problem. -- http://mail.python.org/mailman/listinfo/python-list
How do I change the behavior of the 'python-docs' action in IDLE?
In the Windows version of Python 2.5, pressing F1 brought up the python.chm file. I've just installed 2.6, and the same action opens http://www.python.org/doc/current/. I'd prefer the former behavior. I know how to change the key bindings in config-keys.def, but I think I want to change the action, not the key binding. Thanks. -- http://mail.python.org/mailman/listinfo/python-list
creating classes with mix-ins
I'm writing a class that derives it's functionality from mix-ins. Here's the code: def boilerplate(what): # This used to be a decorator, but all of the ##what = f.__name__ # function bodies turned out to be 'pass'. 'Validate the user, then call the appropriate plug-in.' def template(self, which, username, password, *args): if not self.security.isAuthorised(username, password, which, what): raise Exception('Unauthorised access') return getattr(self.blog, what)(which, *args) template.__name__ = what template.__doc__ = getattr(self.blog, what).__doc__ return template class MetaWeblog(object): def __init__(self, securityHandler=SimpleSecurityHandler, blogHandler=SimpleBlogHandler): self.security = securityHandler() self.blog = blogHandler() newPost = boilerplate('newPost') editPost = boilerplate('editPost') getPost = boilerplate('getPost') # etc, etc, etc I'd like to replace the method definitions with a loop: for what in attr_list: setattr(klass, what, boilerplate(what)) That begs the question of where I define 'klass' and 'attr_list'. Should I use a class decorator, or a metaclass? In favor of decorators is that I can see how to do it; in favor of a metaclass is that I get to learn how to use them. ;-) What are the other pros and cons for each choice? -- http://mail.python.org/mailman/listinfo/python-list
Re: creating classes with mix-ins
On May 11, 1:16 pm, samwyse wrote: > I'm writing a class that derives it's functionality from mix-ins. While waiting, I gave a try at using class decorators. Here's what I came up with: def add_methods(*m_list, **kwds): def wrapper(klass): for m_name in m_list: def template(self, which, username, password, *args): if not self.security.isAuthorised(username, password, which, m_name): raise Exception('Unauthorised access') return getattr(self.blog, m_name)(which, *args) dotted_name = kwds.get('prefix', '') + m_name template.__name__ = dotted_name template.__doc__ = dotted_name setattr(klass, dotted_name, template) return klass return wrapper @add_methods('newPost', 'editPost', 'getPost', 'newMediaObject', 'getCategories', 'getRecentPosts', prefix='metaWeblog.') class MetaWeblog(object): def __init__(self, securityHandler=SimpleSecurityHandler, blogHandler=SimpleBlogHandler): self.security = securityHandler() self.blog = blogHandler() if __name__ == '__main__': server = SimpleXMLRPCServer(("localhost", 8080)) server.register_instance(MetaWeblog()) server.register_introspection_functions() server.serve_forever() The problem that I'm having is that when I call newPost, SimpleBlogHandler.getRecentPosts gets invoked. Apparently add_methods isn't generating unique templates. I think I need to move 'template' into another function, but I'm starting to wonder if metaclasses might work better. Any ideas? -- http://mail.python.org/mailman/listinfo/python-list
Re: creating classes with mix-ins
On May 11, 9:01 pm, Carl Banks wrote: > On May 11, 11:16 am, samwyse wrote: > > > Should I use a class decorator, or a metaclass? > > Here's the thing: unless you have advance knowledge of the methods > defined by self.blog, you can't get the attr_list at class definition > time, which means neither the metaclass nor the decorator would be a > good approach. If that's the case, you should define newPost, > editPost, and whatever other methods of self.blog as ordinary > attributes of self, within the init function. boilerplate would be > the same except you would pass self to it and allow template to use it > from its nested scope (it would no longer be an instance method since > it's an ordinary attribute). > > If you do know what the methods of self.blog will be, then that's > where you get attr_list from. So, for instance, if blogHandler always > returns an object of type Blog, then you could inspect Blog's type > dict to see what methods are defined in it; in fact you probably want > to check the whole MRO for Blog, like this (untested): > > attr_list = [] > for cls in Blog.__mro__: > for value in cls.__dict__: > if is_wrapped_method(value): > attr_list.append(value) > > A metaclass is probably overkill to assign the wrapped blog methods. > I probably wouldn't even bother with the decorator, and just write the > loop after the class definition. Then you can use MetaBlog directly > for klass. > > class MetaBlog(object): > ... > > for what in attr_list: > setattr(MetaBlog, what, boilerplate(what)) > > If it were the kind of thing I found myself doing often I'd refactor > into a decorator. Unfortunately, 'boilerplate()' uses the handlers that I provide when MetaBlog is instantiated. I tried the following, but it didn't work (for reasons that were obvious in retrospect). def instantiate_template(m_name, instance): isAuthorised = instance.security.isAuthorised method_to_wrap = getattr(instance.blog, m_name) def template(self, which, username, password, *args): if not isAuthorised(username, password, which, m_name): raise Exception('Unauthorised access') return method_to_wrap(which, *args) template.__name__ = method_to_wrap.__name__ template.__doc__ = method_to_wrap.__doc__ return template class MetaWeblog(object): def __init__(self, securityHandler=SimpleSecurityHandler, blogHandler=SimpleBlogHandler): self.security = securityHandler() self.blog = blogHandler() # from http://www.xmlrpc.com/metaWeblogApi m_prefix = 'metaWeblog.' m_list = ('newPost', 'editPost', 'getPost', 'newMediaObject', 'getCategories', 'getRecentPosts', ) # Here's where things fell apart for m_name in m_list: dotted_name = m_prefix + m_name method = instantiate_template(m_name, self) setattr(self, dotted_name, method) So, I replaced that last for-loop with this: # Since we're about to monkey-patch the class, we should # make certain that all instances use the same handlers. handlers = (self.security, self.blog) try: assert getattr(self.__class__, '_handlers') == handlers except AttributeError: for m_name in m_list: dotted_name = m_prefix + m_name method = instantiate_template(m_name, self) setattr(self.__class__, dotted_name, method) setattr(self.__class__, '_handlers', handlers) This is good enough for now, since I can't conceive of a reason why MetaBlog would be instantiated more than once. If it were, on the other hand, it would probably be because you wanted to use different handlers. In that case, I think I'd want to use a class factory, something like this: server.register_instance( MetaWeblogFactory(securityHandler, blogHandler)() ) Anyway, thanks for getting me over a conceptual hump. -- http://mail.python.org/mailman/listinfo/python-list
Re: How do I change the behavior of the 'python-docs' action in IDLE?
On Apr 16, 2:02 pm, samwyse wrote: > In the Windows version of Python 2.5, pressing F1 brought up the > python.chm file. I've just installed 2.6, and the same action > openshttp://www.python.org/doc/current/. I'd prefer the former behavior. > I know how to change the key bindings in config-keys.def, but I think > I want to change the action, not the key binding. Thanks. I just installed Python 3.0.1 via the Windows 32-bit installer. Opening "Python Docs" takes me to http://docs.python.org/dev/3.0/, which doesn't exist. Renaming python301.chm to python30.chm or python300.chm doesn't seem to help find that file. HELP! -- http://mail.python.org/mailman/listinfo/python-list
Turning HTMLParser into an iterator
I'm processing some potentially large datasets stored as HTML. I've subclassed HTMLParser so that handle_endtag() accumulates data into a list, which I can then fetch when everything's done. I'd prefer, however, to have handle_endtag() somehow yield values while the input data is still streaming in. I'm sure someone's done something like this before, but I can't figure it out. Can anyone help? Thanks. -- http://mail.python.org/mailman/listinfo/python-list
Re: how to find the last decorator of a chain
On May 30, 6:16 pm, Gabriel wrote: > I have something like this: > > @render(format="a") > @render(format="b") > @ > def view(format, data): > return data > In my understanding this equivalent to: > > render('a', > render('b', > view(***))) Not quite. 'render' is a function of one argument that returns a decorator. So, the equivalent is more like this: view = render('a')(render('b')(view)) or more simply: fb = render('b') view = fb(view) fa = render('a') view = fa(view) > Is there any way to know, in this case, that 'a' is the 'default' format? Will this do? (In case the formatting gets messed up, I've also posted the code to http://python.pastebin.com/f7f229d9d) ##from functools import wraps def render(c): def decorator(f): ##@wraps(f) def wrapper(*args, **kwds): if getattr(wrapper, 'outermost', False): print('outer wrapper', c) else: print('inner wrapper', c) return f(*args, **kwds) return wrapper return decorator def mark_as_top(f): print('marking', f) f.outermost = True ##@wraps(f) return f @mark_as_top @render('a') @render('b') @render('c') @render('d') def f(): pass f() -- http://mail.python.org/mailman/listinfo/python-list
Missing codecs in Python 3.0
I have a Python 2.6 program (a code generator, actually) that tries several methods of compressing a string and chooses the most compact. It then writes out something like this: { encoding='bz2_codec', data = '...'} I'm having two problems converting this to Py3. First is the absence of the bz2_codec, among others. It was very convenient for my program to delay selection of the decoding method until run-time and then have an easy way to load the appropriate code. Is this gone forever from the standard libraries? Second, I would write my data out using the 'string_escape' codec. It, too, has been removed; there's a 'unicode_escape' codec which is similar, but I would rather use a 'byte_escape' codec to produce literals of the form b'asdf'. Unfortunately, there isn't one that I can find. I could use the repr function, but that seems less efficient. Does anyone have any ideas? Thanks. -- http://mail.python.org/mailman/listinfo/python-list
Logging to zero or more destinations
In the Python 2.5 Library Reference, section 14.5.3 (Logging to multiple destinations), an example is given of logging to both a file and the console. This is done by using logging.basicConfig() to configure a log file, and then calling logging.getLogger('').addHandler(console) to add the console. However, in section 14.5.4 (Sending and receiving logging events across a network), a call is made to rootLogger.addHandler(socketHandler), and later it is stated that "On the client side, nothing is printed on the console". Finally, back in section 14.5.2 (Basic example), it's stated that "by default, the root logger is configured to only handle messages with a severity of WARNING or above. The message format is also a configuration default, as is the output destination of the messages - sys.stderr." The only way that I can see for all three statements to be consistent is that the root logger starts with an empty list of handlers, and doesn't instantiate a default handler until either logging.basicConfig() is called, or the first time that a message is logged. This would also seem to imply that there's no way to use an empty handler list (say, if you want to suppress all logging), because the root handler will instantiate a handler for you. Is this correct? P.S. I tried researching this further by myself, but the logging module doesn't come with source (apparently it's written in C?) and I don't have the time to find and download the source to my laptop. Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: re.search much slower then grep on some regular expressions
On Jul 4, 6:43 am, Henning_Thornblad <[EMAIL PROTECTED]> wrote: > What can be the cause of the large difference between re.search and > grep? > While doing a simple grep: > grep '[^ "=]*/' input (input contains 156.000 a in > one row) > doesn't even take a second. > > Is this a bug in python? You might want to look at Plex. http://www.cosc.canterbury.ac.nz/greg.ewing/python/Plex/ "Another advantage of Plex is that it compiles all of the regular expressions into a single DFA. Once that's done, the input can be processed in a time proportional to the number of characters to be scanned, and independent of the number or complexity of the regular expressions. Python's existing regular expression matchers do not have this property. " I haven't tested this, but I think it would do what you want: from Plex import * lexicon = Lexicon([ (Rep(AnyBut(' "='))+Str('/'), TEXT), (AnyBut('\n'), IGNORE), ]) filename = "my_file.txt" f = open(filename, "r") scanner = Scanner(lexicon, f, filename) while 1: token = scanner.read() print token if token[0] is None: break -- http://mail.python.org/mailman/listinfo/python-list
Re: numeric emulation and __pos__
On Jul 7, 6:12 pm, Ethan Furman <[EMAIL PROTECTED]> wrote: > Greetings, List! > > I'm working on a numeric data type for measured values that will keep > track of and limit results to the number of significant digits > originally defined for the values in question. > > I am doing this primarily because I enjoy playing with numbers, and also > to get some experience with unit testing. > > At this point I have the __init__ portion finished, and am starting on > the various operator functions. > > Questions for the group: > > 1) Any reason to support the less common operators? > i.e. <<, >>, &, ^, | > > 2) What, exactly, does .__pos__() do? An example would help, too. 1) Those make much less sense for non-integers. I'd say skip them. 2) It's an overridable no-op that implements the unary plus operator. Unary plus returns its value unchanged, as does __pos__. -- http://mail.python.org/mailman/listinfo/python-list
Re: numeric emulation and __pos__
On Jul 8, 12:34 pm, Ethan Furman <[EMAIL PROTECTED]> wrote: > Anybody have an example of when the unary + actually does something? > Besides the below Decimal example. I'm curious under what circumstances > it would be useful for more than just completeness (although > completeness for it's own sake is important, IMO). Well, as in Decimal, it would be a good operator to use for canonization. Let's say you implement complex numbers as an angle and radius. Then, unary plus could be used to normalize the angle to +/- Pi and the radius to a positive number (by inverting the angle). -- http://mail.python.org/mailman/listinfo/python-list
Re: Logging to zero or more destinations
On Jul 8, 3:01 pm, Rob Wolfe <[EMAIL PROTECTED]> wrote: > samwyse <[EMAIL PROTECTED]> writes: > > P.S. I tried researching this further by myself, but the logging > > module doesn't come with source (apparently it's written in C?) and I > > don't have the time to find and download the source to my laptop. > > Hmmm... that's strange. It is a pure Python package. > > $ ls /usr/lib/python2.5/logging/ > config.py config.pyc handlers.py handlers.pyc __init__.py __init__.pyc > > HTH, > Rob Oops, my bad. I was using IDLE and tried the "Open Module..." command on logging, not logging.something. -- http://mail.python.org/mailman/listinfo/python-list
Re: Impossible to change methods with special names of instances of new-style classes?
On Jul 8, 4:56 pm, Joseph Barillari <[EMAIL PROTECTED]> wrote: > My question is: did something about the way the special method names are > implemented change for new-style classes? Just off the top of my head, I'd guess that it's due to classes already having a default __call__ method, used when you instatiate. Remember, the Python compiler doesn't know the difference between this: a = MyClass instance = a() and this: a = myFunc result = a() -- http://mail.python.org/mailman/listinfo/python-list
Re: re.search much slower then grep on some regular expressions
On Jul 8, 11:01 am, Kris Kennaway <[EMAIL PROTECTED]> wrote: > samwyse wrote: > > You might want to look at Plex. > >http://www.cosc.canterbury.ac.nz/greg.ewing/python/Plex/ > > > "Another advantage of Plex is that it compiles all of the regular > > expressions into a single DFA. Once that's done, the input can be > > processed in a time proportional to the number of characters to be > > scanned, and independent of the number or complexity of the regular > > expressions. Python's existing regular expression matchers do not have > > this property. " > Hmm, unfortunately it's still orders of magnitude slower than grep in my > own application that involves matching lots of strings and regexps > against large files (I killed it after 400 seconds, compared to 1.5 for > grep), and that's leaving aside the much longer compilation time (over a > minute). If the matching was fast then I could possibly pickle the > lexer though (but it's not). That's funny, the compilation is almost instantaneous for me. However, I just tested it to several files, the first containing 4875*'a', the rest each twice the size of the previous. And you're right, for each doubling of the file size, the match take four times as long, meaning O(n^2). 156000*'a' would probably take 8 hours. Here are my results: compile_lexicon() took 0.0236021580595 secs test('file-0.txt') took 24.8322969831 secs test('file-1.txt') took 99.3956799681 secs test('file-2.txt') took 398.349623132 secs And here's my (probably over-engineered) testbed: from __future__ import with_statement from os.path import exists from timeit import Timer from Plex import * filename = "file-%d.txt" def create_files(n): for x in range(0,n): fname = filename % x if not exists(fname): print 'creating', fname with open(fname, 'w') as f: print >>f, (4875*2**x)*'a', def compile_lexicon(): global lexicon lexicon = Lexicon([ (Rep(AnyBut(' "='))+Str('/'), TEXT), (AnyBut('\n'), IGNORE), ]) def test(fname): with open(fname, 'r') as f: scanner = Scanner(lexicon, f, fname) while 1: token = scanner.read() #print token if token[0] is None: break def my_timed_test(func_name, *args): stmt = func_name + '(' + ','.join(map(repr, args)) + ')' t = Timer(stmt, "from __main__ import "+func_name) print stmt, 'took', t.timeit(1), 'secs' if __name__ == '__main__': create_files(6) my_timed_test('compile_lexicon') for x in range(0,4): my_timed_test('test', filename%x) -- http://mail.python.org/mailman/listinfo/python-list
Re: Loading just in time
On Jul 10, 9:45 am, "D'Arcy J.M. Cain" <[EMAIL PROTECTED]> wrote: > I am trying to create a utility module that only loads functions when > they are first called rather than loading everything. I have a bunch > of files in my utility directory with individual methods and for each I > have lines like this in __init__.py: > > def calc_tax(*arg, **name): > from calc_tax import calc_tax as _func_ > calc_tax = _func_ > return _func_(*arg, **name) This doesn't do what you think. The line "calc_tax = _func_" is probably modifying a local variable that is then thrown away. I've got a slightly different (simpler) version to illustrate: === main.py === def calc_tax(*arg, **name): from calc_tax import calc_tax as _func_ #global calc_tax calc_tax = _func_ print '_func_ is', repr(_func_) print 'calc_tax is', repr(calc_tax) return _func_(*arg, **name) print 'before: calc_tax is', repr(calc_tax) result = calc_tax() print 'after: calc_tax is', repr(calc_tax) === calc_tax.py === def calc_tax(*arg, **name): return 42 === end of files === Running main.py gives this: before: calc_tax is _func_ is calc_tax is after: calc_tax is Note that the value of calc_test is the same in the first and last lines. If you uncomment the line "#global calc_tax" and run it again, you get this: before: calc_tax is _func_ is calc_tax is after: calc_tax is Interestingly, neither version gives me a TypeError, no matter how many times I call calc_tax. (BTW, you might want to look up Memoization; it's very similar to what you want to do, and might give you a way to more efficiently code things.) -- http://mail.python.org/mailman/listinfo/python-list
Re: Problems Returning an HTTP 200 Ok Message
On Jul 10, 1:50 pm, Guy Davidson <[EMAIL PROTECTED]> wrote: > Hi Folks, > > I'm having some issues with an small socket based server I'm writing, > and I was hoping I could get some help. > > My code (attached below) us supposed to read an HTTP Post message > coming from a power meter, parse it, and return a proper HTTP 200 Ok > message. The problem is that the socket fails to send the entire > message as one message, creating a fragmented message which the power > meter then fails to read and accept. > > Is there any way to force the socket to send the entire message at > once? Am I doing anything wrong? Is there an easier way to implement > this functionality? By 'message', do you mean a single IP datagram? In general, the answer is no. Each call to 'connection.send()' will (in general, see the next paragraph) transmit as much data as will fit into a single IP datagram, given the current MTU for the transmission circuit. The fact that you're calling it in a loop indicates that the data being sent may be larger than will fit into a datagram. Or, by 'message', do you mean a single TCP segment? Again, the answer is no. Your network stack will try to make the TCP segments the right size to fit within a single IP datagram, leading to the same result as above. >From your description, I get the feeling that your power meter has a broken network stack, and you're trying to program around it. You need to repair the meter. -- http://mail.python.org/mailman/listinfo/python-list
Re: Problems Returning an HTTP 200 Ok Message
On Jul 10, 4:10 pm, Guy Davidson <[EMAIL PROTECTED]> wrote: > I try to send the following message, using the socket.send() command: > > 'HTTP/1.1 200 OK\r\nDate: Thu, 10 July 2008 14:07:50 GMT\r\nServer: > Apache/2.2.8 (Fedora)\r\nX-Powered-By: PHP/5.2.4\r\nContent-Length: 4\r > \nConnection: close\r\nContent-Type: text/html; charset=UTF-8\r\n\r > \n[0]\n' > > However, when I snoop on the packets in wireshark, here's what I see: > > HTTP/1.1 200 Ok: > > HTTP/1.1 200 OK > Date: Wed, 09 July 2008 14:55:50 GMT > Server: Apache/2.2.8 (Fedora) > X-Powered-By: > > Continuation or non-HTTP traffic: > > PHP/5.2.4 > Content-Length: 4 > Connection: close > Content-Type: text/html; charset=UTF-8 > > [0] > > It splits into two packages, which the meter can't read, and the > communication breaks down there. OK, it looks like a single TCP segment is being sent by you (which is consistent with only one socket.send() command being needed), but something along the way to the meter is using an MTU (Maximum Transmission Unit) of about 100 bytes, producing two IP datagrams. How many hops are there between the PC and the meter? Are you sniffing on the same subnet as the PC, the meter, or somewhere in between? MTU is normally set to about 1500 (and MSS is generally MTU-40), but you can generally change these values. You should be able to set the do-not-fragment flag on your IP packets, but that may cause them to get dropped instead of sent. You could also try setting a smaller ICP MSS (Maximum Segment Size), which the meter might be able to assemble, even if it can't handle fragmented IP datagrams. Try http://www.cisco.com/en/US/tech/tk870/tk877/tk880/technologies_tech_note09186a008011a218.shtml#prob_desc for more help. You really need to get a networking guru involved if you want to go down this path. I used to be one, but that was years ago. Or, you can take Gabriel Genellina's advice and try coding smaller responses. -- http://mail.python.org/mailman/listinfo/python-list
Re: Problems Returning an HTTP 200 Ok Message
On Jul 11, 3:46 am, "Gabriel Genellina" <[EMAIL PROTECTED]> wrote: > As Guy Davidson has already pointed out, this is a problem in the meter > TCP implementation, and you should ask the vendor to fix it. That would have been me, not Guy. -- http://mail.python.org/mailman/listinfo/python-list
creating ZIP files on the cheap
I've got an app that's creating Open Office docs; if you don't know, these are actually ZIP files with a different extension. In my case, like many other people, I generating from boilerplate, so only one component (content.xml) of my ZIP file will ever change. Instead of creating the entire ZIP file each time, what is the cheapest way to accomplish my goal? I'd kind-of like to just write the first part of the file as a binary blob, then write my bit, then write most of the table of contents as another blob, and finally write a TOC entry for my bit. Has anyone ever done anything like this? Thanks. -- http://mail.python.org/mailman/listinfo/python-list
class version of func_globals?
Is there any way to get the global namespace of the module in which a class was defined? Answers for both Python 2.x and 3.x will be cheerfully accepted. -- http://mail.python.org/mailman/listinfo/python-list
Re: class version of func_globals?
On Dec 29, 5:18 am, Dave Angel wrote: > samwyse wrote: > > Is there any way to get the global namespace of the module in which a > > class was defined? Answers for both Python 2.x and 3.x will be > > cheerfully accepted. > > I don't know if it's the same in general, but consider the following > sequence in 2.6: > > import sys > > class MyClass(object): > pass > > print "class--", dir(MyClass) > print "module--", dir(MyClass.__module__) > mod = sys.modules[MyClass.__module__] > print mod > print "globals--", dir(mod) > > DaveA Excellent! Exactly what I wanted, but wasn't clever enough to figure out for myself. Thank you very much. -- http://mail.python.org/mailman/listinfo/python-list
Re: Bare Excepts
On Dec 30, 7:23 am, Jean-Michel Pichavant wrote: > Rule N°2: > dont use BARE EXCEPT, or you'll piss off MRAB for good :o). Beside from > kidding, don't use bare except. I inherited some code that used bare excepts *everywhere*. There were about 4K lines of code, IIRC, and I think that they were more except clauses than elses. Eventually, I used sed to add a print_exc() after each one, just so I could figure out what the expected exceptions were. It was so bad that I seriously considered writing a program just to parse all the tracebacks from my instrumented version and then revise the source code for me, but I didn't want to accidentally miss any "real" errors. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to test a URL request in a "while True" loop
On Dec 30, 10:00 am, Brian D wrote: > What I don't understand is how to test for a valid URL request, and > then jump out of the "while True" loop to proceed to another line of > code below the loop. There's probably faulty logic in this approach. I > imagine I should wrap the URL request in a function, and perhaps store > the response as a global variable. > > This is really more of a basic Python logic question than it is a > urllib2 question. There, I've condensed your question to what you really meant to say. You have several approaches. First, let's define some useful objects: >>> max_attempts = 5 >>> def do_something(i): assert 2 < i < 5 Getting back to original question, if you want to limit the number of attempts, don't use a while, use this: >>> for count in xrange(max_attempts): print 'attempt', count+1 do_something(count+1) attempt 1 Traceback (most recent call last): File "", line 3, in do_something(count+1) File "", line 2, in do_something assert 2 < i < 5 AssertionError If you want to keep exceptions from ending the loop prematurely, you add this: >>> for count in xrange(max_attempts): print 'attempt', count+1 try: do_something(count+1) except StandardError: pass Note that bare except clauses are *evil* and should be avoided. Most exceptions derive from StandardError, so trap that if you want to catch errors. Finally, to stop iterating when the errors cease, do this: >>> try: for count in xrange(max_attempts): print 'attempt', count+1 try: do_something(count+1) raise StopIteration except StandardError: pass except StopIteration: pass attempt 1 attempt 2 attempt 3 Note that StopIteration doesn't derive from StandardError, because it's not an error, it's a notification. So, throw it if and when you want to stop iterating. BTW, note that you don't have to wrap your code in a function. do_something could be replaced with it's body and everything would still work. -- http://mail.python.org/mailman/listinfo/python-list
enhancing 'list'
Consider this a wish list. I know I'm unlikely to get any of these in time for for my birthday, but still I felt the need to toss it out and see what happens. Lately, I've slinging around a lot of lists, and there are some simple things I'd like to do that just aren't there. s.count(x[, cmp[, key]]) - return number of i‘s for which s[i] == x. 'cmp' specifies a custom comparison function of two arguments, as in '.sort'. 'key' specifies a custom key extraction function of one argument. s.index(x[, i[, j[, cmp[, key) - return smallest k such that s[k] == x and i <= k < j. 'cmp' and 'key' are as above. s.rindex(x[, i[, j[, cmp[, key) - return largest k such that s[k] == x and i <= k < j. 'cmp' and 'key' are as above. There are two overlapping proposals here. One is to add the .rindex method, which strings already have. The other is to extend the optional arguments of .sort to all other methods that test for item equality. One last thing, the Python 2.6.2 spec says .count and .index only apply to mutable sequence types. I see no reason why they (and .rindex) couldn't also apply to immutable sequences (tuples, in particular). -- http://mail.python.org/mailman/listinfo/python-list
Re: enhancing 'list'
On Jan 18, 1:56 am, Terry Reedy wrote: > On 1/17/2010 5:37 PM, samwyse wrote: > > > > > > > Consider this a wish list. I know I'm unlikely to get any of these in > > time for for my birthday, but still I felt the need to toss it out and > > see what happens. > > > Lately, I've slinging around a lot of lists, and there are some simple > > things I'd like to do that just aren't there. > > > s.count(x[, cmp[, key]]) > > - return number of i‘s for which s[i] == x. 'cmp' specifies a custom > > comparison function of two arguments, as in '.sort'. 'key' specifies > > a custom key extraction function of one argument. > > s.index(x[, i[, j[, cmp[, key) > > - return smallest k such that s[k] == x and i<= k< j. 'cmp' and > > 'key' are as above. > > s.rindex(x[, i[, j[, cmp[, key) > > - return largest k such that s[k] == x and i<= k< j. 'cmp' and > > 'key' are as above. > > > There are two overlapping proposals here. One is to add the .rindex > > method, which strings already have. The other is to extend the > > optional arguments of .sort to all other methods that test for item > > equality. > > > One last thing, the Python 2.6.2 spec says .count and .index only > > apply to mutable sequence types. I see no reason why they > > (and .rindex) couldn't also apply to immutable sequences (tuples, in > > particular). > > In 3.x, tuple does have those methods, even though the doc is not clear > (unless fixed by now). That's good to hear. Perhaps I should have tried them directyly, but my 3.1 docs still echo the 2.x docs, which only show them for immutable sequences. -- http://mail.python.org/mailman/listinfo/python-list
Re: enhancing 'list'
On Jan 18, 3:06 am, Peter Otten <__pete...@web.de> wrote: > samwyse wrote: > > Lately, I've slinging around a lot of lists, and there are some simple > > things I'd like to do that just aren't there. > > > s.count(x[, cmp[, key]]) > > - return number of i‘s for which s[i] == x. 'cmp' specifies a custom > > comparison function of two arguments, as in '.sort'. 'key' specifies > > a custom key extraction function of one argument. > > What's your use case exactly? If I were to enhance count/index/rindex I > would go for the simpler > > >>> missing = object() > >>> class List(list): > > ... def count(self, value=missing, predicate=missing): > ... if value is missing: > ... if predicate is missing: > ... raise TypeError > ... return sum(1 for item in self if predicate(item)) > ... else: > ... if predicate is not missing: > ... raise TypeError > ... return list.count(self, value) > ...>>> items = List(range(10)) > >>> items.count(7) > 1 > >>> items.count(predicate=lambda item: item%3) > > 6 > > which nicely covers all applications I can imagine. > > Peter That is a good idea. However, I was looking more at the simplicity of building of ideas that are already present in .sort. And this implementation is pretty simple as well. >>> class List(list): import __builtin__ def count(self, value, cmp=__builtin__.cmp): return sum(1 for item in self if not cmp(item, value)) >>> items = List(range(10)) >>> items.count(7) 1 >>> items.count(3, lambda a, b: not a%b) # My way 6 >>> items.count(Ellipsis, lambda a, b: not a%3) # Your way 6 As a side note, wouldn't it be nice if '...' could be used in more places than just slices? IMHO, a useful idiom would be to use it to signify "irrelevant" or "don't care", as opposed to 'None' which (in my mind, at least) signifies "missing" or "unknown". -- http://mail.python.org/mailman/listinfo/python-list
Re: enhancing 'list'
On Jan 17, 11:30 pm, Asun Friere wrote: > On Jan 18, 9:37 am, samwyse wrote: > > > Consider this a wish list. I know I'm unlikely to get any of these in > > time for for my birthday, but still I felt the need to toss it out and > > see what happens. > > > Lately, I've slinging around a lot of lists, and there are some simple > > things I'd like to do that just aren't there. > > If memory serves me correctly, it has been possible to subclass 'built- > in' types since Py2.2 or thereabouts. True, but I've had bad experiences doing that. See, for example, http://groups.google.com/group/comp.lang.python/browse_thread/thread/10cfe2affc265ac where I tried to subclass 'int'. More importantly, subclassing means that people have to keep re-inventing the same methods. Having a single implementation would save time, not to mention the speed advantages of implementing them in the hosting language (C, Java, .NET, etc). -- http://mail.python.org/mailman/listinfo/python-list
Re: The answer
On Jan 17, 8:30 pm, Jive Dadson wrote: > Okay, with your help I've figured it out. Instructions are below, but > read the caveat by Ben Fenny in this thread. All this stuff is good for > one default version of Python only. The PYTHONPATH described below, for > example, cannot specify a version number. Yes, that's a pain in the > butt, but there's no way around it. If you switch versions, you may > have to delete all the .pyc files that will show up in the module > folders. Python ought to check them to see if they are valid, but I do > not know if it does so. > > These instructions are for MS Windows. > > 1) Create your modules folder. Let's say it's named "Modules." The > documentation calls it a "package." > > 2) In an explorer window or on the desktop, right click on My Computer, > and select Properties. > > 3) Select the Advanced tab, and click on Environment Variables near the > bottom. > > 4) Look for an environment variable named PYTHONPATH. > > a) If you do not find one, create one using the New button(s). I > don't know if it has to be in User Variables or System Variables. To > save time experimenting, I just put one in both. For the value, put the > full path of the folder Modules. > > b) If there's already a PYTHONPATH, Edit it, adding a semi-colon > and the full path of folder Module to the end. > > 5) Put your module folders into the folder Module. > > 6) (Here's a really arcane bit.) Into each module folder, put a file > named __init__.py. It will be executed when you load the module. It > can be empty, but it has to be there or else the module folder will be > ignored. In your original thread, you never quite said why you can't use site- packages and .pth files. Are you not allowed to modify your local installation? If you are writing something for distribution to others, then site-packages and .pth files are the best way to go, since they don't assume any particular operating system. If you can't (or won't) use them, then just create Module as a sub-directory of wherever your program lives, since that directory is always prepended to PYTHONPATH. If you need to use the same module from multiple directories, most modern operating systems support symbolic links; if you're using Windows, well, here's a nickel kid, get yourself a better computer (http://farm1.static.flickr.com/ 89/240711122_f9888e5a3b_o.jpg). I don't think that __init__.py is very arcane, since it is described in detail in the documentation. It's also a great place to use the standard site.addsitedir() function, which is another platform independent way to manipulate Python's search path. -- http://mail.python.org/mailman/listinfo/python-list
Re: enhancing 'list'
On Jan 18, 6:20 am, Peter Otten <__pete...@web.de> wrote: > Note that the cmp() builtin and the cmp parameter for list.sort() are gone > in Python 3. I've got Python 3 installed, and am using it for most new development. In this case case, however, I'm writing for the Google App Engine, which is stuck at 2.5. :( (Curiously, no matter how I order my PATH, the wrong version seems to appear first more than half the time! I'm seriously considering renaming all my Python 3 code to use a .py3 file extension.) > samwyse wrote: > > As a side note, wouldn't it be nice if '...' could be used in more > > places than just slices? IMHO, a useful idiom would be to use it to > > signify "irrelevant" or "don't care", as opposed to 'None' which (in > > my mind, at least) signifies "missing" or "unknown". > > That is a pretty subtle distinction... Hey, I'm a pretty subtle person... > I prefer keyword arguments, but in Python 3 you can use the ellipsis literal > freely: > > >>> ... == ... > True > >>> [..., 42, ...].count(...) > > 2 > > Peter I must have either missed or forgotten about that. Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: Parse a log file
On Jan 18, 6:52 am, "kak...@gmail.com" wrote: > Hello to all! > I want to parse a log file with the following format for > example: > TIMESTAMPE Operation FileName > Bytes > 12/Jan/2010:16:04:59 +0200 EXISTS sample3.3gp 37151 > 12/Jan/2010:16:04:59 +0200 EXISTS sample3.3gp 37151 > 12/Jan/2010:16:04:59 +0200 EXISTS sample3.3gp 37151 > 12/Jan/2010:16:04:59 +0200 EXISTS sample3.3gp 37151 > 12/Jan/2010:16:04:59 +0200 EXISTS sample3.3gp 37151 > 12/Jan/2010:16:05:05 +0200 DELETE sample3.3gp 37151 > > How can i count the operations for a month(e.g total of 40 Operations, > 30 exists, 10 delete?) > Any tips? > > Thanks in advance > Antonis time.strptime(string[, format]) Parse a string representing a time according to a format. The return value is a struct_time as returned by gmtime() or localtime(). The format parameter uses the same directives as those used by strftime (); it defaults to "%a %b %d %H:%M:%S %Y" which matches the formatting returned by ctime(). If string cannot be parsed according to format, or if it has excess data after parsing, ValueError is raised. The default values used to fill in any missing data when more accurate values cannot be inferred are (1900, 1, 1, 0, 0, 0, 0, 1, -1). >>> import time >>> ts='12/Jan/2010:16:04:59 +0200' >>> time.strptime(ts[:-6], '%d/%b/%Y:%H:%M:%S') time.struct_time(tm_year=2010, tm_mon=1, tm_mday=12, tm_hour=16, tm_min=4, tm_sec=59, tm_wday=1, tm_yday=12, tm_isdst=-1) I leave the conversion of the last six characters (the time zone offset) as an exercise for the student. :) -- http://mail.python.org/mailman/listinfo/python-list
Looking for a buffered/windowed iterator
I have Python program that lets me interact with a bunch of files. Unfortunately, the program assumes that the bunch is fairly small, and I have thousands of files on relatively slow storage. Just creating a list of the file names takes several minutes, so I'm planning to replace the list with an iterator in another thread. However, each file requires several seconds to load before I can work with it. The current code alleviates this via a thread that loads the next file while I'm examining the current one. I'd like my new iterator to provide a fixed window around the current item. I've looked at the pairwise recipe, but it doesn't allow me to peek at items within the window (to generate thumbnails, etc), and I've looked at arrayterator, but it divides the stream into small contiguous blocks where crossing a block boundary is relatively expensive. Previous discussions in c.l.py (primarily those that propose new functions to be added to itertools) claim that people do this all the time, but seem woefully short of actual examples. Before I possibly re-invent the wheel(*), could someone point me to some actual code that approximates what I want to do? Thanks. (*) Re-inventing a wheel is generally pretty simple. But then you discover that you also need to invert axle grease, a leaf spring suspension, etc. -- http://mail.python.org/mailman/listinfo/python-list
Re: python along or bash combined with python (for manipulating files)
On Oct 13, 9:13 pm, Peng Yu wrote: > Bash is easy to use on manipulating files and directories (like change > name or create links, etc) and on calling external programs. For > simple functions, bash along is enough. However, bash does not support > the complex functions. Python has a richer library that could provide > support for complex functions (such compute the relative path between > two paths). > > I'm wondering for a task that can not be done with bash along whether > it would be better to do in pure python or with a mix of both python > and bash. What I care is mostly coding speed and a little bit > maintainability (but not much). Can somebody provide some experience > on when to combine python and bash and when to use pure python? Scripting languages try to optimize gluing disparate programs together to accomplish a task; bash excels at this. Programing languages try to optimize finding the solution to a problem; Python excels at this. Generally, I try to stick to one language per problem, be it bash, C+ +, Java, Perl or Python. Bash scripts translate easily into the others, so you don't lose much time if you decide you started with the wrong language. Countering that, I also maintain a "toolbox" of programs that I can call upon when needed. In those cases, I don't hesitate to call a program that I've written in any language from a bash script. BTW, I actually prefer ksh to bash, but YMMV. -- http://mail.python.org/mailman/listinfo/python-list
Re: New syntax for blocks
On Nov 10, 1:23 pm, r wrote: > Forgive me if i don't properly explain the problem but i think the > following syntax would be quite beneficial to replace some redundant > "if's" in python code. > > if something_that_returns_value() as value: > #do something with value > > # Which can replace the following syntactical construct... > > value = something_that_returns_value() > if value: > #do something with value I don't like the proposed syntax. I know, it's copied from the "with" statement, but it makes the assignment look like an afterthought. Plus, it's not good English when read aloud. If you want something useful, wait two years for the moratorium to expire and then figure out how to augment the "for" statement with an "if" clause, as is currently done in comprehensions. In other words, instead of this: "for" target_list "in" expression_list ":" suite let's have this: "for" target_list "in" expression_list [ "if" expression_nocond ] ":" suite You don't save much typing, but you really do save one indention level. OTOH, I can see the use of an else-clause following the 'for' as being even more confusing to anyone new to the language. And there's also the fact that an expression_list consists of conditional_expressions, which potentially use "if". You could probably get the parser to figure it out based on the presence of the "else" clause, but it wouldn't be easy. -- http://mail.python.org/mailman/listinfo/python-list
Re: Python C api: create a new object class
On Nov 10, 1:09 pm, "lallous" wrote: > Hello > > I have 3 questions, hope someone can help: > > 1) > How can I create an instance class in Python, currently I do: > > class empty: > pass > > Then anytime I want that class (which I treat like a dictionary): > > o = empty() > o.myattr = 1 > etc > > Is there is a one line syntax to instantiate an instance? I think that you want this: class c(object): def __init__(self, **kwds): self.__dict__ = kwds x = c(a=1, b=2) print x.a, x.b -- http://mail.python.org/mailman/listinfo/python-list
Re: python simply not scaleable enough for google?
On Nov 11, 3:57 am, "Robert P. J. Day" wrote: > http://groups.google.com/group/unladen-swallow/browse_thread/thread/4... > > thoughts? Google's already given us its thoughts: http://developers.slashdot.org/story/09/11/11/0210212/Go-Googles-New-Open-Source-Programming-Language -- http://mail.python.org/mailman/listinfo/python-list
Re: UnicodeDecodeError? Argh! Nothing works! I'm tired and hurting and...
On Nov 24, 4:43 pm, Steven D'Aprano wrote: > Oh yes, and people using Windows can't use maildir because (1) it doesn't > allow colons in names, and (2) it doesn't have atomic renames. Neither of > these are insurmountable problems: an implementation could substitute > another character for the colon, and while that would be a technical > violation of the standard, it would still work. And the lack of atomic > renames would simply mean that implementations have to be more careful > about not having two threads writing to the one mailbox at the same time. A common work around for the former is to URL encode the names, which let's you stick all sorts of odd characters. I'm afraid I can't help with the latter, though. -- http://mail.python.org/mailman/listinfo/python-list
optparse/argparse for cgi/wsgi?
Has anyone ever built some sort of optparse/argparse module for cgi/ wsgi programs? I can see why a straight port wouldn't work, but a module that can organize parameter handling for web pages seems like a good idea, especially if it provided a standard collection of both client- and server-side validation processes, easy internationalization, and a way to create customizable help pages. -- http://mail.python.org/mailman/listinfo/python-list
Re: Proposed changes to logging defaults
On Dec 9, 6:12 pm, Vinay Sajip wrote: > Some changes are being proposed to how logging works in default > configurations. > > Briefly - when a logging event occurs which needs to be output to some > log, the behaviour of the logging package when no explicit logging > configuration is provided will change, most likely to log those events > to sys.stderr with a default format. I'm in favor of this change. I've long wished that I could just add lots of warning/error/info logging to a script and have it just work without having to spend time configuring the logging system. -- http://mail.python.org/mailman/listinfo/python-list
simple (I hope!) problem
I'm writing for the Google app engine and have stubbed my toe yet again on a simple obstacle. Non-trivial app engines programs require the import of several modules that aren't normally in my PYTHONPATH. I'd like to be able to test my code outside of the app engine framework. I've tried several solutions in the past that worked but weren't particularly elegant or portable. Now I've had a new idea. Here's my latest attempt: import os, re if __name__ == '__main__': pass else from google.appengine.ext import webapp register = webapp.template.create_template_register() This works great, except my code makes use of the resister object in several places, like this: register.filter(emptylines) Fortunately, I don't need the functionality of the object, I just want something that won't generate an error when I use it. So, what is the quickest way to to create such an object (replacing the 'pass' in my first snippet). My solution is this: class C: def filter(self, *args, **kwds): pass register = C() but it seems like I should be able to do something "better", as measured by lines of code, faking more than just a 'filter' method, or both. Any ideas? Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: simple integer subclass
On Aug 2, 6:52 pm, Andreas Pfrengle wrote: > I'm trying to define a subclass of int called int1. An int1-object > shall behave exactly like an int-object, with the only difference that > the displayed value shall be value + 1 (it will be used to display > array indices starting at 1 instead of 0). Right now I have: > > class int1(int): > def __str__(self): > return int.__str__(self + 1) > > However, if I calculate with int1 and int- (or other number) objects, > the result is always coerced to an int (or other number object), e.g: > a = int1(5) > b = 5 > print a # "6" > print a+b #"10" > > How can I tell int1 to be the "default integer object"? Do I need to > overload *every* mathematical operation method of int, or is there an > easier way? I had a similar problem a few years ago, and couldn't find a solution then. The thread from back then may shed some light on your problem. http://groups.google.com/group/comp.lang.python/browse_thread/thread/10cfe2affc265ac/2ad03b121c1c6489 -- http://mail.python.org/mailman/listinfo/python-list
Re: Behavior of re.split on empty strings is unexpected
On Aug 2, 12:34 pm, John Nagle wrote: > The regular expression "split" behaves slightly differently than string > split: I'm going to argue that it's the string split that's behaving oddly. To see why, let's first look at some simple CSV values: cat,dog ,missing,,values, How many fields are on each line and what are they? Here's what re.split(',') says: >>> re.split(',', 'cat,dog') ['cat', 'dog'] >>> re.split(',', ',missing,,values,') ['', 'missing', '', 'values', ''] Note that the presence of missing values is clearly flagged via the presence of empty strings in the results. Now let's look at string split: >>> 'cat,dog'.split(',') ['cat', 'dog'] >>> ',missing,,values,'.split(',') ['', 'missing', '', 'values', ''] It's the same results. Let's try it again, but replacing the commas with spaces. >>> re.split(' ', 'cat dog') ['cat', 'dog'] >>> re.split(' ', ' missing values ') ['', 'missing', '', 'values', ''] >>> 'cat dog'.split(' ') ['cat', 'dog'] >>> ' missing values '.split(' ') ['', 'missing', '', 'values', ''] It's the same results; however many people don't like these results because they feel that whitespace occupies a privileged role. People generally agree that a string of consecutive commas means missing values, but a string of consecutive spaces just means someone held the space-bar down too long. To accommodate this viewpoint, the string split is special-cased to behave differently when None is passed as a separator. First, it splits on any number of whitespace characters, like this: >>> re.split('\s+', ' missing values ') ['', 'missing', 'values', ''] >>> re.split('\s+', 'cat dog') ['cat', 'dog'] But it also eliminates any empty strings from the head and tail of the list, because that's what people generally expect when splitting on whitespace: >>> 'cat dog'.split(None) ['cat', 'dog'] >>> ' missing values '.split(None) ['missing', 'values'] -- http://mail.python.org/mailman/listinfo/python-list