Re: how to convert string function to string method?
Dr. Phillip M. Feldman a écrit : Bruno- You've made some excellent suggestions, and I'm always grateful for the opportunity to learn. Glad to know I've been of any help !-) My revised code appears below. Philllip def strip_pairs(s, open='([{\'"', close=')]}\'"'): """ OVERVIEW This function strips matching pairs of characters from the beginning and end of the input string `s`. If `s` begins with a character in `open` and ends with the corresponding character in `close` (see below), both are removed from the string. This process continues until no further matching pairs can be removed. INPUTS `open` and `close`: These arguments, which must be equal-length strings, specify matching start-of-scope and end-of-scope characters. The same character may appear in both `open` and `close`; single and double quotes conventionally match themselves. By default, `open` contains a left parenthesis, left square bracket, left curly bracket, single quote, and double quote), and `close` contains the corresponding characters.""" if not isinstance(s,(str,unicode)): raise TypeError, '`s` must be a string (str or unicode).' Might be a bit more helpful (for the programmer using your function) to specify what 's' actually is. Also, the recommanded way to raise exceptions is to use the 'call' syntax, ie: if not isinstance(s,(str,unicode)): raise TypeError("'s' must be a str or unicode, got '%s'" % type(s)) if not isinstance(open,(str,unicode)) or not isinstance(close,(str,unicode)): raise TypeError, '`open` and `close` must be strings (str or unicode).' Mmmm I still wonder why you wouldn't accept a tuple or list of chars here. if len(open) != len(close): raise ValueError, \ '\'open\' and \'close\' arguments must be equal-length strings.' while len(s) >= 2: # Check whether first character of `s` is in `open`: i= open.find(s[0]) # If `s` does not begin with a character from `open`, there are no more # pairs to be stripped: if i == -1: break wrt/ readability, it might be better to put the break statement on it's own line - but you can probably count this one as more of a personnal preference than a guideline !-) # If `s` does not begin and end with matching characters, there are no # more pairs to be stripped: if s[-1] != close[i]: break # Strip the first and last character from `s`: s= s[1:-1] return s Steven (D'Aprano) posted a possibly interesting implementation. Might be worth timeit'ing both. -- http://mail.python.org/mailman/listinfo/python-list
Re: how to convert string function to string method?
Bruno- You've made some excellent suggestions, and I'm always grateful for the opportunity to learn. My revised code appears below. Philllip def strip_pairs(s, open='([{\'"', close=')]}\'"'): """ OVERVIEW This function strips matching pairs of characters from the beginning and end of the input string `s`. If `s` begins with a character in `open` and ends with the corresponding character in `close` (see below), both are removed from the string. This process continues until no further matching pairs can be removed. INPUTS `open` and `close`: These arguments, which must be equal-length strings, specify matching start-of-scope and end-of-scope characters. The same character may appear in both `open` and `close`; single and double quotes conventionally match themselves. By default, `open` contains a left parenthesis, left square bracket, left curly bracket, single quote, and double quote), and `close` contains the corresponding characters.""" if not isinstance(s,(str,unicode)): raise TypeError, '`s` must be a string (str or unicode).' if not isinstance(open,(str,unicode)) or not isinstance(close,(str,unicode)): raise TypeError, '`open` and `close` must be strings (str or unicode).' if len(open) != len(close): raise ValueError, \ '\'open\' and \'close\' arguments must be equal-length strings.' while len(s) >= 2: # Check whether first character of `s` is in `open`: i= open.find(s[0]) # If `s` does not begin with a character from `open`, there are no more # pairs to be stripped: if i == -1: break # If `s` does not begin and end with matching characters, there are no # more pairs to be stripped: if s[-1] != close[i]: break # Strip the first and last character from `s`: s= s[1:-1] return s -- View this message in context: http://old.nabble.com/how-to-convert-string-function-to-string-method--tp26673209p26688035.html Sent from the Python - python-list mailing list archive at Nabble.com. -- http://mail.python.org/mailman/listinfo/python-list
Re: how to convert string function to string method?
Steven D'Aprano wrote: On Sun, 06 Dec 2009 22:47:48 -0800, Dr. Phillip M. Feldman wrote: I wrote a handy-dandy function (see below) called "strip_pairs" for stripping matching pairs of characters from the beginning and end of a string. This function works, but I would like to be able to invoke it as a string method rather than as a function. Is this possible? Not exactly. You can subclass string and add such a method: class MyString(str): def strip_pairs(self, ...): ... but then you have to convert every string to a MyString before you use it. That way leads to madness. Better to just use a function. Don't worry, you're allowed to mix functional and OO code :) Unlike certain other languages, Python is not designed around a fetish for calling all functions as methods. s.func(arg) is immediately translated to cls.func(s,arg) where cls is either the class of s or some superclass thereof. Directly writing mod.func(s,arg), where mod is some module, is just as good. Methods have three purposes: bundle several related functions in a class-specific namespace; inheritance; mapping of operations, like '+', to class-specific (special) methods. Modules are an alernative namespace bundle. Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: how to convert string function to string method?
r0g a écrit : (snip) > I've never tried it but I think it is possible to inject new methods into existing classes, see... Doesn't work for most builtin types - for both performances and sanity reasons. -- http://mail.python.org/mailman/listinfo/python-list
Re: how to convert string function to string method?
On Sun, 06 Dec 2009 22:47:48 -0800, Dr. Phillip M. Feldman wrote: > I wrote a handy-dandy function (see below) called "strip_pairs" for > stripping matching pairs of characters from the beginning and end of a > string. This function works, but I would like to be able to invoke it > as a string method rather than as a function. Is this possible? Not exactly. You can subclass string and add such a method: class MyString(str): def strip_pairs(self, ...): ... but then you have to convert every string to a MyString before you use it. That way leads to madness. Better to just use a function. Don't worry, you're allowed to mix functional and OO code :) As for the function, I think we can re-write it to be a bit more Pythonic. We start with a helper function. (Since it's a one-liner, that's not strictly necessary.) def bracketed_by(s, open, close): """Return True if string s is bracketed by open and close pairs.""" # I'm too lazy to put proper error handling here... return s.startswith(open) and s.endswith(close) # UNTESTED def strip_pairs(s, open='([{\'"', close=')]}\'"'): if len(open) != len(close): raise ValueError( "'open' and 'close' arguments must be equal length strings.") if not isinstance(s, basestring): # FIX ME: this wrongly fails on UserString arguments. raise TypeError('argument must be a string') pairs = zip(open, close) while any(bracketed_by(s, a, b) for (a,b) in pairs): s = s[1:-1] return s The above is written for simplicity rather than efficiency -- for small strings, say, under a couple of megabytes, it is likely to be faster than a more "clever" algorithm. If you are routinely dealing with strings which are tens of megabytes in size, bracketed by dozens or hundreds of pairs of brackets, then the above may be a little slow. But for small strings, it will probably be faster than a routine which tries to be smarter at avoiding copying strings. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: how to convert string function to string method?
Dr. Phillip M. Feldman a écrit : I wrote a handy-dandy function (see below) called "strip_pairs" for stripping matching pairs of characters from the beginning and end of a string. This function works, but I would like to be able to invoke it as a string method rather than as a function. Is this possible? No. Basic type (strings/unicode, numerics, lists, tuples, dicts etc) are not "opened" to monkeypatching. Partly for performance reasons, partly to avoid the insanity that we've seen in the Ruby world where everyone and it's little sisters extends basic types with tons of more or less usefull and often conflicting features. def strip_pairs(s=None, open='([{\'"', close=')]}\'"'): Why a default value of None for the first param ??? """This function strips matching pairs of characters from the beginning and end of the input string `s`. `open` and `close` specify corresponding pairs of characters, and must be equal-length strings. If `s` begins with a character in `open` and ends with the corresponding character in `close`, both are removed from the string. This process continues until no further matching pairs can be removed.""" if len(open) != len(close): raise Exception, \ '\'open\' and \'close\' arguments must be strings of equal length.' Please use proper exception types. Here you want a ValueError. Also, you just dont care whether open and close are proper strings - any sequence of characters would do. # If input is missing or is not of type `str` (or `unicode`), return None: if s is None or not isinstance(s,(str,unicode)): return None If s is None, it won't be a str or unicode instance, so the test is redundant !-) But anyway : if this function is supposed to operate on strings, don't accept None (and even less provide it as default), and don't fail silently - you should really raise a TypeError here IMHO. while len(s) >= 2: # Check whether first character of `s` is in `open`: i= open.find(s[0]) # If `s` does not begin with a character from `open`, there are no more # pairs to be stripped: if i == -1: break # If `s` does not begin and end with matching characters, there are no # more pairs to be stripped: if s[-1] != close[i]: break # Strip the first and last character from `s`: s= s[1:-1] return s HTH -- http://mail.python.org/mailman/listinfo/python-list
Re: how to convert string function to string method?
Dr. Phillip M. Feldman wrote: > I wrote a handy-dandy function (see below) called "strip_pairs" for stripping > matching pairs of characters from the beginning and end of a string. This > function works, but I would like to be able to invoke it as a string method > rather than as a function. Is this possible? > > def strip_pairs(s=None, open='([{\'"', close=')]}\'"'): >"""This function strips matching pairs of characters from the beginning > and >end of the input string `s`. `open` and `close` specify corresponding > pairs >of characters, and must be equal-length strings. If `s` begins with a >character in `open` and ends with the corresponding character in `close`, >both are removed from the string. This process continues until no > further >matching pairs can be removed.""" > >if len(open) != len(close): raise Exception, \ > '\'open\' and \'close\' arguments must be strings of equal length.' > ># If input is missing or is not of type `str` (or `unicode`), return > None: >if s is None or not isinstance(s,(str,unicode)): return None > >while len(s) >= 2: > > # Check whether first character of `s` is in `open`: > i= open.find(s[0]) > > # If `s` does not begin with a character from `open`, there are no > more > # pairs to be stripped: > if i == -1: break > > # If `s` does not begin and end with matching characters, there are no > # more pairs to be stripped: > if s[-1] != close[i]: break > > # Strip the first and last character from `s`: > s= s[1:-1] > >return s I've never tried it but I think it is possible to inject new methods into existing classes, see... http://www.daniel-lemire.com/blog/archives/2005/12/21/metaclass-programming-in-python/ Not sure how good an idea it would be though, I have heard it refered to as "monkey patching" and I can imagine doing it to classes as fundamental as the string class could have negative performace consequences. Roger. -- http://mail.python.org/mailman/listinfo/python-list
Re: how to convert string function to string method?
Dr. Phillip M. Feldman wrote: > I wrote a handy-dandy function (see below) called "strip_pairs" for > stripping > matching pairs of characters from the beginning and end of a string. This > function works, but I would like to be able to invoke it as a string > method > rather than as a function. Is this possible? This requires a feature called "open classes" (Ruby has them). It is not possible in Python, at least for built-in types like str. Peter -- http://mail.python.org/mailman/listinfo/python-list
Re: how to convert string function to string method?
On Sun, Dec 6, 2009 at 10:47 PM, Dr. Phillip M. Feldman < pfeld...@verizon.net> wrote: > > I wrote a handy-dandy function (see below) called "strip_pairs" for > stripping > matching pairs of characters from the beginning and end of a string. This > function works, but I would like to be able to invoke it as a string method > rather than as a function. Is this possible? > No. String objects are immutable and you can not set new attributes/methods on the type itself. Really the best thing to do in this case is to just have this in an easy to access library, and call it as a function and not a string method. The only alternative is to create a string subtype which has a new method-- but that would require all the strings you're using to be this subclass. E.g. you'd have to do MyString(regular_String) for each. This is really IMHO unwieldy and not really worth the effort -- just put strip_pairs into a library and call it as a function. --S -- http://mail.python.org/mailman/listinfo/python-list
how to convert string function to string method?
I wrote a handy-dandy function (see below) called "strip_pairs" for stripping matching pairs of characters from the beginning and end of a string. This function works, but I would like to be able to invoke it as a string method rather than as a function. Is this possible? def strip_pairs(s=None, open='([{\'"', close=')]}\'"'): """This function strips matching pairs of characters from the beginning and end of the input string `s`. `open` and `close` specify corresponding pairs of characters, and must be equal-length strings. If `s` begins with a character in `open` and ends with the corresponding character in `close`, both are removed from the string. This process continues until no further matching pairs can be removed.""" if len(open) != len(close): raise Exception, \ '\'open\' and \'close\' arguments must be strings of equal length.' # If input is missing or is not of type `str` (or `unicode`), return None: if s is None or not isinstance(s,(str,unicode)): return None while len(s) >= 2: # Check whether first character of `s` is in `open`: i= open.find(s[0]) # If `s` does not begin with a character from `open`, there are no more # pairs to be stripped: if i == -1: break # If `s` does not begin and end with matching characters, there are no # more pairs to be stripped: if s[-1] != close[i]: break # Strip the first and last character from `s`: s= s[1:-1] return s -- View this message in context: http://old.nabble.com/how-to-convert-string-function-to-string-method--tp26673209p26673209.html Sent from the Python - python-list mailing list archive at Nabble.com. -- http://mail.python.org/mailman/listinfo/python-list