Need a way to test for 8-bit-or-unicode-string
I'm finding more and more the need to test whether an object is a string, including both 8-bit and Unicode strings. Current practice seems to be: if type(x) in (str, unicode): or (more verbose but more b/w compatible): if type(x) in (types.StringType, types.UnicodeType): or (using a variable recently added to types -- I'm not sure this was a good idea): if type(x) in types.StringTypes: all of which break if type(x) is a *subclass* of str or unicode. The alternative: if isinstance(x, str) or isinstance(x, unicode): is apparently too much typing. Some alternatives that have been proposed already: - Create a common base class of str and unicode, which should be an abstract class. This is the most OO solution, but I can't think of a good name; abstractstring is too long, AbstractString or String are uncommon naming conventions for built-in types, 'string' would almost work except that it's already the name of a very common module.[*] - Make str a subclass of unicode (or vice versa). This can't be done because subclassing requires implementation inheritance, in particular the instance structure layout must overlap. Also, this would make it hard to check for either str or unicode. - Create a new service function, IsString(x) or isString(x) or isstring(x), that's a shortcut for "isinstance(x, str) or isinstance(x, unicode)". The question them becomes where to put this: as a builtin, in types.py, or somewhere else... Preferences please? --Guido van Rossum (home page: http://www.python.org/~guido/) [*] For a while I toyed with the idea of calling the abstract base class 'string', and hacking import so that sys.modules['string'] is the string class. The abstract base class should then have methods that invoke the concrete implementations, so that string.split(s) would be the same as s.split(). This would be compatible with previous uses of the string module! string.letters etc. could then be class variables. Unfortunately this broke down when I realized that the signature of string.join() is wrong for the string module: the the string.join function is string.join(sequence, stringobject) while the signature of the string method is join(stringobject, sequence). So much for that idea... :-) (BTW this shows to me again that the method signature is right and the function signature is wrong. But even my time machine isn't powerful enough to fix this.) (Hm, it could be saved by making string.join() accept the arguments in either order. Gross. :-)
Guido van Rossum wrote:
if isinstance(x, str) or isinstance(x, unicode):
is apparently too much typing.
Perhaps we could extend isinstance(). How about isinstance(x, str, unicode) or isinstance(x, (str, unicode)) This is a common problem not limited to string types. I often want to test if something is a tuple or a list for example. Neil
Guido van Rossum wrote:
if isinstance(x, str) or isinstance(x, unicode):
is apparently too much typing.
Perhaps we could extend isinstance(). How about
isinstance(x, str, unicode)
or
isinstance(x, (str, unicode))
This is a common problem not limited to string types. I often want to test if something is a tuple or a list for example.
You may be on to something. It certainly saves me inventing a new name! I'll think about it a bit more... --Guido van Rossum (home page: http://www.python.org/~guido/)
Neil Schemenauer wrote:
isinstance(x, str, unicode)
...
This is a common problem not limited to string types. I often want to test if something is a tuple or a list for example.
Guido van Rossum writes:
You may be on to something. It certainly saves me inventing a new name! I'll think about it a bit more...
I like this approach. It also doesn't preclude the other changes. -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> PythonLabs at Zope Corporation
GvR> if isinstance(x, str) or isinstance(x, unicode): > > is GvR> apparently too much typing. NS> Perhaps we could extend isinstance(). How about NS> isinstance(x, str, unicode) NS> or NS> isinstance(x, (str, unicode)) NS> This is a common problem not limited to string types. I often NS> want to test if something is a tuple or a list for example. That's an interesting idea, but please use the former signature, not the latter. And what would it return? It needs to return a true value on success, but maybe instead of returning 1, it might be more useful to return the type argument that matched, e.g.:
isinstance('', str, unicode) <type 'str'> isinstance(u'', str, unicode) <type 'unicode'> isinstance((), list, dictionary, tuple) <type 'tuple'> isinstance(7, list, dictionary, tuple) 0
-Barry
Barry A. Warsaw writes:
And what would it return? It needs to return a true value on success, but maybe instead of returning 1, it might be more useful to return the type argument that matched, e.g.:
Ugh! If that's what you want, make it explicit in the code: for t in ListType, TupleType, ...: if isinstance(obj, t): break else: raise Exception('no match!') -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> PythonLabs at Zope Corporation
"FLD" == Fred L Drake, <fdrake@acm.org> writes:
FLD> for t in ListType, TupleType, ...: FLD> if isinstance(obj, t): FLD> break FLD> else: FLD> raise Exception('no match!') Or: try: raise obj except (ListType, TupleType): pass except: raise TypeError, ... with-apologies-to-tim-ly y'rs, Jeremy
GvR> if isinstance(x, str) or isinstance(x, unicode): > > is GvR> apparently too much typing.
NS> Perhaps we could extend isinstance(). How about
NS> isinstance(x, str, unicode)
NS> or
NS> isinstance(x, (str, unicode))
NS> This is a common problem not limited to string types. I often NS> want to test if something is a tuple or a list for example.
That's an interesting idea, but please use the former signature, not the latter.
Why? The varargs signature makes it less convenient (and less efficient!) to pre-calculate the list of types. It also makes it harder to implement this in PyObject_IsInstance(), so that C code can use this convenience. Finally, if I already know the meaning of isinstance(x, y), then when I encounter isinstance(x, (y, z)) for the first time, it's very easy to guess the meaning. The meaning of isinstance(x, y, z) is much more murky: z could be an optional argument specifying some other modification of the basic isinstance().
And what would it return? It needs to return a true value on success, but maybe instead of returning 1, it might be more useful to return the type argument that matched, e.g.:
isinstance('', str, unicode) <type 'str'> isinstance(u'', str, unicode) <type 'unicode'> isinstance((), list, dictionary, tuple) <type 'tuple'> isinstance(7, list, dictionary, tuple) 0
Here I agree with Fred: too much hackery combined in one function. And what's the use case? --Guido van Rossum (home page: http://www.python.org/~guido/)
Here's an implementation of Neil's idea. *** abstract.c 2001/10/01 17:10:18 2.83 --- abstract.c 2001/10/05 15:49:04 *************** *** 1805,1810 **** --- 1805,1829 ---- else if (PyType_Check(cls)) { retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls); } + else if (PySequence_Check(cls)) { + int i, n; + + cls = PySequence_Fast( + cls, "isinstance() arg 2 is an unacceptable sequence"); + if (cls == NULL) + return -1; + n = PySequence_Size(cls); + if (n < 0) + retval = -1; + for (i = 0; i < n; i++) { + retval = PyObject_IsInstance( + inst, PySequence_Fast_GET_ITEM(cls, i)); + if (retval != 0) + break; + } + Py_DECREF(cls); + return retval; + } else if (!PyInstance_Check(inst)) { if (__class__ == NULL) { __class__ = PyString_FromString("__class__"); *************** *** 1827,1833 **** if (retval < 0) { PyErr_SetString(PyExc_TypeError, ! "isinstance() arg 2 must be a class or type"); } return retval; } --- 1846,1853 ---- if (retval < 0) { PyErr_SetString(PyExc_TypeError, ! "isinstance() arg 2 must be a class or type " ! "or tuple of those"); } return retval; } --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido van Rossum writes:
Here's an implementation of Neil's idea.
Commit this and I'll take care of the documentation. ;-)
I'll wait 24 hours. Who knows what I think after the anesthetics in my jaw wear off... :-) --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido van Rossum wrote:
Here's an implementation of Neil's idea.
*** abstract.c 2001/10/01 17:10:18 2.83 --- abstract.c 2001/10/05 15:49:04 *************** *** 1805,1810 **** --- 1805,1829 ---- else if (PyType_Check(cls)) { retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls); } + else if (PySequence_Check(cls)) { + int i, n;
Is is possible that a type also passes PySequence_Check? If so, that could lead to confusing behavior. Neil
*** 1805,1810 **** --- 1805,1829 ---- else if (PyType_Check(cls)) { retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls); } + else if (PySequence_Check(cls)) { + int i, n;
Is is possible that a type also passes PySequence_Check? If so, that could lead to confusing behavior.
The only way a type could pass PySequence_Check is if someone subclasses 'type' and adds a __getitem__ method. In that case, it's appropriate that PyType_Check() has prevalence. Also, adding __getitem__ to a type seems to serve no purpose, so I'm not worried about this (and yes, I had thought about this :-). --Guido van Rossum (home page: http://www.python.org/~guido/)
[I know we've already reached agreement, but I feel the need to stick my oar in.] Barry A. Warsaw wrote:
NS> Perhaps we could extend isinstance(). How about
NS> isinstance(x, str, unicode)
NS> or
NS> isinstance(x, (str, unicode))
NS> This is a common problem not limited to string types. I often NS> want to test if something is a tuple or a list for example.
That's an interesting idea, but please use the former signature, not the latter.
Ewww, gross, spit spit spit. ;-) At least with the latter, you can do: stringtype = (str, unicode) isinstance(x, stringtype) Hmmmm... Or can you? -- --- Aahz (@pobox.com) Hugs and backrubs -- I break Rule 6 <*> http://www.rahul.net/aahz/ Androgynous poly kinky vanilla queer het Pythonista We must not let the evil of a few trample the freedoms of the many.
[Aahz]
At least with the latter, you can do:
stringtype = (str, unicode) isinstance(x, stringtype)
Hmmmm... Or can you?
Yes -- it's the value of the expression that counts, not how it's spelled. You can even nest these tuples:
int_types = int, long file_types = file, def fori(x): ... return isinstance(x, (int_types, file_types)) ... fori(43) 1 fori(43L) 1 import sys fori(sys.stdin) 1 fori(43.0) 0
Guido van Rossum wrote:
I'm finding more and more the need to test whether an object is a string, including both 8-bit and Unicode strings. Current practice seems to be:
if type(x) in (str, unicode):
or (more verbose but more b/w compatible):
if type(x) in (types.StringType, types.UnicodeType):
or (using a variable recently added to types -- I'm not sure this was a good idea):
if type(x) in types.StringTypes:
all of which break if type(x) is a *subclass* of str or unicode. The alternative:
if isinstance(x, str) or isinstance(x, unicode):
is apparently too much typing.
Some alternatives that have been proposed already:
- Create a common base class of str and unicode, which should be an abstract class. This is the most OO solution, but I can't think of a good name; abstractstring is too long, AbstractString or String are uncommon naming conventions for built-in types, 'string' would almost work except that it's already the name of a very common module.[*]
+1. This would be nice and the same could be done for sequences, file-like objects and other common currently interface-defined object categories. About the naming: how about numberclass, stringclass, sequenceclass, fileclass ?! Then you could write: if isinstance(obj, stringclass): ... which looks OK and is not too much typing. The advantage of this approach is that it can be extended to other types and classes as well (much like you can currently do with the Python exceptions). With the new type logic in place, how hard would it be making the existing built-in types subclasses of these base types ? (also: is there a run-time penalty for this ?)
- Make str a subclass of unicode (or vice versa). This can't be done because subclassing requires implementation inheritance, in particular the instance structure layout must overlap. Also, this would make it hard to check for either str or unicode.
-0. This would be hard to get right because the two objects use a very different struct layout. Could be an option in the long run though.
- Create a new service function, IsString(x) or isString(x) or isstring(x), that's a shortcut for "isinstance(x, str) or isinstance(x, unicode)". The question them becomes where to put this: as a builtin, in types.py, or somewhere else...
-1. This mechanism can not be extended by e.g. UserStrings.
Preferences please?
--Guido van Rossum (home page: http://www.python.org/~guido/)
[*] For a while I toyed with the idea of calling the abstract base class 'string', and hacking import so that sys.modules['string'] is the string class. The abstract base class should then have methods that invoke the concrete implementations, so that string.split(s) would be the same as s.split(). This would be compatible with previous uses of the string module! string.letters etc. could then be class variables. Unfortunately this broke down when I realized that the signature of string.join() is wrong for the string module: the the string.join function is string.join(sequence, stringobject) while the signature of the string method is join(stringobject, sequence). So much for that idea... :-) (BTW this shows to me again that the method signature is right and the function signature is wrong. But even my time machine isn't powerful enough to fix this.) (Hm, it could be saved by making string.join() accept the arguments in either order. Gross. :-)
Indeed. :-) -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Consulting & Company: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/
- Create a common base class of str and unicode, which should be an abstract class. This is the most OO solution, but I can't think of a good name; abstractstring is too long, AbstractString or String are uncommon naming conventions for built-in types, 'string' would almost work except that it's already the name of a very common module.[*]
+1. This would be nice and the same could be done for sequences, file-like objects and other common currently interface-defined object categories.
About the naming: how about numberclass, stringclass, sequenceclass, fileclass ?!
Then you could write:
if isinstance(obj, stringclass): ...
which looks OK and is not too much typing.
Hm, I don't know if "class" is the proper suffix to mean "abstract base class". I think I'll either call it "numberbase" or "abstractnumber".
The advantage of this approach is that it can be extended to other types and classes as well (much like you can currently do with the Python exceptions).
Yup, that's why it's the most OO solution. :-)
With the new type logic in place, how hard would it be making the existing built-in types subclasses of these base types ?
That would be a prerequisite!
(also: is there a run-time penalty for this ?)
None.
- Make str a subclass of unicode (or vice versa). This can't be done because subclassing requires implementation inheritance, in particular the instance structure layout must overlap. Also, this would make it hard to check for either str or unicode.
-0. This would be hard to get right because the two objects use a very different struct layout. Could be an option in the long run though.
I tried to explany that I already gave it a -1. ;-)
- Create a new service function, IsString(x) or isString(x) or isstring(x), that's a shortcut for "isinstance(x, str) or isinstance(x, unicode)". The question them becomes where to put this: as a builtin, in types.py, or somewhere else...
-1. This mechanism can not be extended by e.g. UserStrings.
Good point. There's still Neil's isinstance(x, (str, unicode)) which gives the programmer more freedom: maybe some function wants to support lists and tuples but not all sequences. I'm currently +1 on introducing names for abstract base classes *and* extensing isinstance()'s API. --Guido van Rossum (home page: http://www.python.org/~guido/)
"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> I'm currently +1 on introducing names for abstract base GvR> classes *and* extensing isinstance()'s API. I'm worried about the abstract base class idea, because it might lead us down a path of having a complicated class hierarchy in order to provide completeness. E.g. should "strings" be a sequencebase, as well as a stringbase? And what does a sequencebase /mean/? Will we push to try to include protocols/interfaces into this mix, so that we'll end up defining abstract classes for all the deep-mojo interfaces? Maybe we'll want to have abstract base classes for file objects so things like file and StringIO's can have them as a common base class? In any event, I think the isinstance() extension is a simple, clean, and (mostly :) uncontroversial change, so I'm also +1 on doing that now. Adding a set of abstract base classes and hooking them up with the existing concrete data types seems much murkier to me, and of greater long range impact, so I'm -1 on the idea, at least until it gets PEP'd. -Barry
GvR> I'm currently +1 on introducing names for abstract base GvR> classes *and* extensing isinstance()'s API.
I'm worried about the abstract base class idea, because it might lead us down a path of having a complicated class hierarchy in order to provide completeness.
Yes, that's a danger. I'm currently thinking about adding a small number of abstract base classes, corresponding to the groups of basic concrete data types in Python: numberbase, integerbase, sequencebase, stringbase, mappingbase, filebase. And I'm not even sure of these! Practically, I only see a use for stringbase and integerbase, since these have two concrete subclasses; the others are just to make the OO zealots happy. :-)
E.g. should "strings" be a sequencebase, as well as a stringbase?
Yes. Any way you can think of that checks for a "sequence" will consider strings to be sequences, unless you make explicit exceptions.
And what does a sequencebase /mean/?
Whatever I want it to mean. :-) The latest code for sequence-ness tests for sq_getitem != NULL, and I think that's reasonable.
Will we push to try to include protocols/interfaces into this mix, so that we'll end up defining abstract classes for all the deep-mojo interfaces?
I'd prefer not to.
Maybe we'll want to have abstract base classes for file objects so things like file and StringIO's can have them as a common base class?
That's currently hard. I don't think we can make StringIO a new-style class, and classic classes can't inherit from new-style classes (not even abstract ones).
In any event, I think the isinstance() extension is a simple, clean, and (mostly :) uncontroversial change, so I'm also +1 on doing that now.
Yes.
Adding a set of abstract base classes and hooking them up with the existing concrete data types seems much murkier to me, and of greater long range impact, so I'm -1 on the idea, at least until it gets PEP'd.
I'm at best +0 myself -- I have more thinking to do... I've *mostly* convinced myself that stringbase is a good idea. But even there, the existence of the buffer API makes the semantics slightly murky. --Guido van Rossum (home page: http://www.python.org/~guido/)
"Barry A. Warsaw" wrote:
"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> I'm currently +1 on introducing names for abstract base GvR> classes *and* extensing isinstance()'s API.
I'm worried about the abstract base class idea, because it might lead us down a path of having a complicated class hierarchy in order to provide completeness.
Since these are abstract classes (basically names for what we now loosly call interface, e.g. file-like object, sequence-like object etc.) this very shallow hierarchy wouldn't hurt all that much. Sure, strings are sequences, so they stringbase would have to be a subclass of sequencebase, but I don't think we'll ever get more than 3 levels deep in the abstract class hierarchy.
E.g. should "strings" be a sequencebase, as well as a stringbase? And what does a sequencebase /mean/?
Good point. There's PySequence_Check(), but we'll have to discuss this at some point anyway and come up with definitions for the currently used fuzzy terms "sequence", "number", "string", and so on.
Will we push to try to include protocols/interfaces into this mix, so that we'll end up defining abstract classes for all the deep-mojo interfaces? Maybe we'll want to have abstract base classes for file objects so things like file and StringIO's can have them as a common base class?
In any event, I think the isinstance() extension is a simple, clean, and (mostly :) uncontroversial change, so I'm also +1 on doing that now.
Adding a set of abstract base classes and hooking them up with the existing concrete data types seems much murkier to me, and of greater long range impact, so I'm -1 on the idea, at least until it gets PEP'd.
Are you sure about the -1 ? Using abstract base classes seems like a natural thing to do in an OO-language like Python while the isinstance() hack would not allow you to use your own UserList subclass for code which was written with sequences as input. -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Consulting & Company: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/
"M" == M <mal@lemburg.com> writes:
M> Are you sure about the -1 ? Using abstract base classes seems M> like a natural thing to do in an OO-language like Python while M> the isinstance() hack would not allow you to use your own M> UserList subclass for code which was written with sequences as M> input. Yes, I'm sure: we need a PEP first. Ideally it would answer some of the questions raised above, and it would lay out the class hierarchy. -Barry
Barry A. Warsaw writes:
Yes, I'm sure: we need a PEP first. Ideally it would answer some of the questions raised above, and it would lay out the class hierarchy.
Sounds to me like you just volunteered. And on that note, its time for some cheap Chinese food... -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> PythonLabs at Zope Corporation
"Fred" == Fred L Drake, Jr <fdrake@acm.org> writes:
>> Yes, I'm sure: we need a PEP first. Ideally it would answer >> some of the questions raised above, and it would lay out the >> class hierarchy. Fred> Sounds to me like you just volunteered. Fred> And on that note, its time for some cheap Chinese food... I think the drop in your BKPL (blood Kung Pao level) has affected your hearing. Please, hurry to boost it back up! sound-of-one-chopstick-clapping-ly y'rs, -Barry
Yes, I'm sure: we need a PEP first. Ideally it would answer some of the questions raised above, and it would lay out the class hierarchy.
The more I think about this, the more I agree that we need a PEP first: there are lots of potential traps. Maybe the biggest danger: declaring an abstract base class for e.g. "sequence-ness" would encourage programmers to test isinstance(x, sequencebase) when all they *really* need is something that supports the __getitem__ protocol. This would encourage writing code that is less polymorphic than it could be, and that would be a real loss. --Guido van Rossum (home page: http://www.python.org/~guido/)
"Barry A. Warsaw" wrote:
"M" == M <mal@lemburg.com> writes:
M> Are you sure about the -1 ? Using abstract base classes seems M> like a natural thing to do in an OO-language like Python while M> the isinstance() hack would not allow you to use your own M> UserList subclass for code which was written with sequences as M> input.
Yes, I'm sure: we need a PEP first. Ideally it would answer some of the questions raised above, and it would lay out the class hierarchy.
Maybe I wasn't clear enough: Of course we need a PEP for these names, their intended meaning as object category abstraction and interface placeholder. Too late for Python 2.2, but probably a nice project for 2.3. -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Consulting & Company: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/
Now that the introduction of a class hierarchy is dead, I'd like to move forward with the isinstance(x, (A, B, C...)) patch. Followup question: should I also implement issubclass(X, (A, B, C...))? It's consistent to do so, but it's more work (issubclass is a bit murkier due to the "abstract subclass" support), and I'm not sure that it has the same benefits... --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido van Rossum writes:
Followup question: should I also implement issubclass(X, (A, B, C...))?
It's consistent to do so, but it's more work (issubclass is a bit murkier due to the "abstract subclass" support), and I'm not sure that it has the same benefits...
They're similar, but they're usage is not. Let's keep issubclass() simple until we know there's a reason to change it. -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> PythonLabs at Zope Corporation
Guido van Rossum wrote:
Now that the introduction of a class hierarchy is dead,
Is it ? I didn't see any messages on the list saying that the idea is dead -- only that a PEP is needed and that it cannot be done for 2.2.
I'd like to move forward with the isinstance(x, (A, B, C...)) patch.
Followup question: should I also implement issubclass(X, (A, B, C...))?
It's consistent to do so, but it's more work (issubclass is a bit murkier due to the "abstract subclass" support), and I'm not sure that it has the same benefits...
-- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Consulting & Company: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/
Guido van Rossum wrote:
Now that the introduction of a class hierarchy is dead,
Is it ? I didn't see any messages on the list saying that the idea is dead -- only that a PEP is needed and that it cannot be done for 2.2.
Sorry, I meant that the introduction of a hierarchy in 2.2 is dead. --Guido van Rossum (home page: http://www.python.org/~guido/)
"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> There's still Neil's isinstance(x, (str, unicode)) which gives GvR> the programmer more freedom: maybe some function wants to GvR> support lists and tuples but not all sequences. GvR> I'm currently +1 on introducing names for abstract base classes GvR> *and* extensing isinstance()'s API. +1. Jeremy
On 05 October 2001, Guido van Rossum said:
- Create a new service function, IsString(x) or isString(x) or isstring(x), that's a shortcut for "isinstance(x, str) or isinstance(x, unicode)". The question them becomes where to put this: as a builtin, in types.py, or somewhere else...
I've thought Python should have this for a long time. But Marc-Andre's point pretty much shoots it down, unless you make isstring(x) sugar for isinstance(x, (str, unicode)) Hmmm. It's a very small dose of sugar, but I like it all the same.
[...] (BTW this shows to me again that the method signature is right and the function signature is wrong. But even my time machine isn't powerful enough to fix this.) (Hm, it could be saved by making string.join() accept the arguments in either order. Gross. :-)
Note that a certain infamous April Fool's post from a few years back said that that was what Python 1.6 would do. I wasn't serious, either. ;-) Greg -- Greg Ward - just another /P(erl|ython)/ hacker gward@python.net http://starship.python.net/~gward/ LILO boot: linux init=/usr/bin/emacs
[Guido]
... [*] For a while I toyed with the idea of calling the abstract base class 'string', and hacking import so that sys.modules['string'] is the string class. The abstract base class should then have methods that invoke the concrete implementations, so that string.split(s) would be the same as s.split(). ... Unfortunately this broke down when I realized that the signature of string.join() is wrong for the string module: the string.join function is string.join(sequence, stringobject) while the signature of the string method is join(stringobject, sequence). ... (Hm, it could be saved by making string.join() accept the arguments in either order. Gross. :-)
Luckily, it's also hopeless:
string.join('abc', ' - ') 'a - b - c'
That is, since strings are also sequences, there's no way to disambiguate the pass-2-strings case. Although, if you ask me, it's obvious I wanted the result shown instead of ' abc-abc ' <wink>.
participants (10)
-
aahz@rahul.net -
barry@zope.com -
Fred L. Drake, Jr. -
Greg Ward -
Guido van Rossum -
Jeremy Hylton -
jeremy@zope.com -
M.-A. Lemburg -
Neil Schemenauer -
Tim Peters