Jason Orendorff wrote:
On 5/11/06, Vladimir 'Yu' Stepanov
wrote: If for Python-3000 similar it will be shown concerning types str(), int(), complex() and so on, and the type of exceptions will strongly vary, it will make problematic redefinition of behavior of function of sorting.
I don't see what you mean by "redefinition of behavior of function of sorting". Is this something a Python programmer might want to do? Can you give an example?
It can be shown concerning external types. When everyone them we shall compare to any internal type, but not with each other. It concerns functions and the methods realized through CPython API. For example types of the whole greater numbers of different mathematical libraries. Or in case of use of several different representation of character arrays. One more example of work with a database which is more realistic. For Python-3000 it will be possible to use comparison only compatible types. There can be a problem to sort types of data incompatible for comparison. ------------------------------------------------------------ conn = MySQLdb.connect(...) cu = conn.cursor() cu.execute(""" CREATE TABLE bigtable ( id INT NOT NULL AUTO_INCREMENT, group_id INT NULL, value VARCHAR(255) NOT NULL, PRIMARY KEY (id) )""") for query in ( "INSERT INTO bigtable VALUES (NULL, 50, 'i am lazy')", "INSERT INTO bigtable VALUES (NULL, 20, 'i am very lazy')", "INSERT INTO bigtable VALUES (NULL, 19, 'i am very very lazy')", "INSERT INTO bigtable VALUES (NULL, 40, 'i am very very very lazy :)')", "INSERT INTO bigtable VALUES (NULL, NULL, 'Something different')" ): cu.execute(query) cu.execute("SELECT * FROM bigtable ORDER BY id") lst = [ r for r in cu ] ... do something in given order ... lst.sort(cmp=lambda a, b: cmp(a[1], b[1])) ------------------------------------------------------------ If it is required to sort records on a column group_id it hardly will be possible to us for python-3000 as numbers in a column group_id will alternate with None values. Certainly it is possible to filter the list preliminary. But it will not be effective. Especially, if to assume, that sorted values can have some various incompatible types (it already beyond the framework of the given example). The essence of my offer consists in at first to admit check of types due to fast mechanisms CPython of methods, and only in case of incompatibility of types of data to use spare model of comparison, only if it is necessary. Creation of uniform exception should facilitate creation of a design try-except. Class of exceptions TypeError have wide using. For functions and methods of comparison the specialized class is necessary. In fact nobody uses class StopIteration for generation of messages on a error :) Other example when classes of different modules are used, and it is necessary to sort them (see attached "example1.py").
On 5/16/06, Vladimir 'Yu' Stepanov
wrote: It will be possible it conveniently to use as exception of management by a stream, for indication of necessity to involve `.__r(eq|ne|le|lt|ge|gt|cmp)__()' a method. This kind of a class can carry out function, similarly to StopIteration for `.next()'.
There are no .__r(eq|ne|le|lt|ge|gt|cmp)__() methods, for a logical reason which you might enjoy deducing yourself...
Oops :) I has simply hastened. About __rcmp__ has once read through, and only here has emerged in memory when about it already all to think have forgotten. As inopportunely.
At present time similar function is carried out with exception NotImplemented. This exception is generated in a number of mathematical operations. For this reason I ask to consider an opportunity of creation of a new class.
Can you explain this? NotImplemented isn't an exception. (NotImplementedError is, but that's something quite different.)
I was mistaken. Sorry. It is valid not a class of exceptions.
NotImplemented has exactly one purpose in Python, as far as I can tell. What mathematical operations do you mean?
At multiplication/division/addition/subtraction/binary of operation/etc - if types are non-comparable (binary_op1 in abstract.c). Very universal element. CPython API will transform returned element NotImplemented to generation of exception TypeError. Whether it is good? In my opinion thus it is possible to hide a mistake of programming. As an example the attached file example2.py. Thanks. #!/usr/local/bin/python import types class CompareError: pass # class in module1 class A: uniform_global_sort_criterion = 1 def __init__(self, val): self.val = val def __cmp__(self, other): if type(self) is type(other) and self.__class__ == other.__class__: return cmp(self.val, other.val) raise CompareError def __repr__(self): return "%s(%d)" % (self.__class__.__name__, self.val) # class in module2 class B: uniform_global_sort_criterion = 2 def __init__(self, value): self.value = value def __cmp__(self, other): if type(self) is type(other) and self.__class__ == other.__class__: return cmp(self.value, other.value) raise CompareError def __repr__(self): return "%s(%d)" % (self.__class__.__name__, self.value) lst = [ A(50), B(25), A(75), B(100), A(1) ] def compare_not_compatable(a, b): try: return cmp(a, b) except CompareError: return cmp(a.uniform_global_sort_criterion, b.uniform_global_sort_criterion) lst.sort(compare_not_compatable) print lst #!/usr/local/bin/python import types import operator import sys _total_ordering_of_types = TOOT = { types.NoneType: 0, types.BooleanType: 100, types.IntType: 101, types.LongType: 102, types.FloatType: 103, types.ComplexType: 104, types.InstanceType: 105, types.StringType: 200, types.UnicodeType: 201, } def compare_realpart(a, b): try: # BEGIN: Emulation python3000 if type(a) is not type(b) and ( not operator.isNumberType(a) or not operator.isNumberType(b) ): raise TypeError("python3000: not-comparable types", (a,b)) # END: Emulation python3000 return cmp(a, b) except TypeError: # for complex and None try: # BEGIN: Emulation python3000 a2 = getattr(a, 'real', a) b2 = getattr(b, 'real', b) if type(a2) is not type(b2) and ( not operator.isNumberType(a2) or not operator.isNumberType(b2) ): raise TypeError("python3000: not-comparable types", (a2,b2)) # END: Emulation python3000 return cmp(getattr(a, 'real', a), getattr(b, 'real', b)) except TypeError: # for None value return cmp(TOOT[type(a)], TOOT[type(b)]) class proxy2number: def __init__(self, val): self.val = val def __cmp__(self, other): if type(other) is types.InstanceType and issubclass(other.__class__, self.__class__): return compare_realpart(self.val, other.val) self._check_type(other) return compare_realpart(self.val, other) def __str__(self): return "%s(%s)" % (self.__class__.__name__, self.val) __repr__ = __str__ # If it is forgotten @staticmethod that exception TypeError is generated #@staticmethod def _check_type(val): if not operator.isNumberType(val): raise TypeError("compare error") # Okay lst = [ proxy2number(10), 1, 18, proxy2number(11+1j), 10+1.2j, 13, -91, -12+100j, None, 17 ] lst.sort(compare_realpart) print lst