8938
Comment: questions on interface examples
|
← Revision 28 as of 2008-11-15 13:59:38 ⇥
9459
converted to 1.6 markup
|
Deletions are marked like this. | Additions are marked like this. |
Line 3: | Line 3: |
['''News Update:''' some ideas from this wiki page are being incorporated into [[http://python.org/dev/peps/pep-3119/|PEP 3119]].] |
|
Line 6: | Line 9: |
* How to handle optional and keyword parameters to methods, such as the ''cmp'' parameter to the "sort" method on {{{MutableSequence}}}? Are they different methods with and without the parameter? Are they just keyword methods, and don't affect the method differentiation? | * How to handle optional and keyword parameters to methods, such as the ''cmp'' parameter to the "sort" method on {{{MutableSequence}}}? Are they different methods with and without the parameter? Are they just keyword methods, and don't affect the method differentiation? [+1 to drop 'cmp' completely and make 'key' the first positional arg] * What is the real relationship between Sequence, Mapping, Set, and Dict? Isn't a Sequence also a mapping (of integer index values to Object sequence values)? Isn't a Dict also a Set (of key values)? |
Line 8: | Line 12: |
* Currently, {{{Boolean}}} is a subtype of {{{Integer}}}, which is odd. But we still want a way to test any {{{Object}}} for "trueness". Should {{{Boolean}}} be an abstract type that's mixed-in to {{{Object}}}, or a concrete type that inherits from {{{Object}}} (thus implying that non-Boolean {{{Object}}}s may exist)? I've added a "true()" method to {{{Object}}}, which is simply a way of coercing it to a {{{Boolean}}} value (perhaps it should be called "boolean()"). | * Currently, {{{Boolean}}} is a subtype of {{{Integer}}}, which is odd. But we still want a way to test any {{{Object}}} for "trueness". Should {{{Boolean}}} be an abstract type that's mixed-in to {{{Object}}}, or a concrete type that inherits from {{{Object}}} (thus implying that non-Boolean {{{Object}}}s may exist)? I've added a "true()" method to {{{Object}}}, which is simply a way of coercing it to a {{{Boolean}}} value (perhaps it should be called "boolean()"). [+1 for mixin] |
Line 19: | Line 23: |
# presumable for "is" we compare the ids of the two objects id () => Integer ## # Why is id an integer? That is convenient in current CPython # (which never moves objects, so can use an address), but perhaps # not in other implementations. The only real requirement is that # it be comparable (== and != -- I'm not even sure about sorting) # to other ids. ## |
# presumably for "is" we compare the ids of the two objects id () => Comparable |
Line 31: | Line 26: |
# the __str__ method | # we rename __str__ to "printable_rendition" |
Line 33: | Line 28: |
### # huh? Are you saying it has a __str__, or it meets a "printable" # interface, or ..? ### |
|
Line 41: | Line 30: |
getattr (String name) => Object setattr (String name, Object value) delattr (String name) => Object TypeSequence (Sequence): # sequence of Type objects |
|
Line 45: | Line 40: |
supertypes () => Sequence ### # is it strictly a Sequence of Types? (or types?) # (and/or interfaces?) ### # interfaces yields flattened list of all interface types this # implements interfaces () => Sequence Ellipsis (Object): # contains only the single value represented by three dots ThreeDots |
supertypes () => TypeSequence # interfaces yields flattened list of all interface types this implements interfaces () => TypeSequence |
Line 61: | Line 45: |
# only a single value of this type | # according to the language reference manual, the Null type contains only one value, "None" |
Line 63: | Line 47: |
################ # How is this different from None? Or are you saying that the # Null interface is like the NoneType? ################ |
|
Line 81: | Line 60: |
# according to Jim Jewett, only < is currently used for ordering | |
Line 82: | Line 62: |
greater_than (Object) => Boolean ## # What about <=, >=? # Currently, only < is used for ordering ## |
|
Line 119: | Line 94: |
# let's rename __iter__ to "iterator" | |
Line 128: | Line 104: |
next () => other | next () => Object |
Line 132: | Line 108: |
len () => Integer | # we keep "len" as a mandatory method -- should we? And why isn't it "size"? len () => Integer |
Line 134: | Line 111: |
Set (Container): |
# we rename __getitem__ to "get" get (Object key) => Object MutableContainer (Container): # we rename __setitem__ to "add" # may quite easily raise KeyError when "key" is of the wrong type add (Object key, Object value) # we rename __delitem__ to "remove" remove (Object key) Set: |
Line 146: | Line 132: |
contains (Sequence) => Sequence | # this "contains" method looks for sub-sequences # how do we differentiate it from the Container method "contains()"? # should it be called "subsequence"? covers (Sequence) => Boolean |
Line 149: | Line 138: |
slice (Integer start, Integer end = None, Integer step = None) => Object | slice (Integer start, Integer end = None, Integer step = None) => Sequence |
Line 160: | Line 149: |
MutableSequence (Sequence): | MutableSequence (Sequence, MutableContainer): # append just calls "add(len(self), Object)" |
Line 162: | Line 152: |
insert (Integer position, Object) => self | |
Line 190: | Line 179: |
# extra version of "get" which takes a default value | |
Line 191: | Line 181: |
set (Object key, Object value) | |
Line 196: | Line 185: |
copy () => Mapping | shallow_copy () => Mapping |
Line 213: | Line 202: |
Dict (Object, Mapping, Container): | Dict (Object, Mapping, MutableContainer): |
Line 239: | Line 228: |
BinaryOutputStream: | BinaryOutputStream (OutputStream): |
Line 267: | Line 256: |
---- CategoryLanguage |
Possible Python 3K Class Tree?
[News Update: some ideas from this wiki page are being incorporated into PEP 3119.]
This page contain an incomplete thinking-out-loud description of a re-factoring of the base and built-in Python types into a set of Abstract Base Classes (ABCs) and concrete types. This would probably be a good time to enumerate the exceptions various basic operations can raise, as well.
Some questions:
How to handle optional and keyword parameters to methods, such as the cmp parameter to the "sort" method on MutableSequence? Are they different methods with and without the parameter? Are they just keyword methods, and don't affect the method differentiation? [+1 to drop 'cmp' completely and make 'key' the first positional arg]
- What is the real relationship between Sequence, Mapping, Set, and Dict? Isn't a Sequence also a mapping (of integer index values to Object sequence values)? Isn't a Dict also a Set (of key values)?
Should the MutableSequence interface be further broken up -- for instance, a deque may not be appropriate for sorting?
Currently, Boolean is a subtype of Integer, which is odd. But we still want a way to test any Object for "trueness". Should Boolean be an abstract type that's mixed-in to Object, or a concrete type that inherits from Object (thus implying that non-Boolean Objects may exist)? I've added a "true()" method to Object, which is simply a way of coercing it to a Boolean value (perhaps it should be called "boolean()"). [+1 for mixin]
Should destructive operations on MutableSequence return the sequence? They don't currently, but this would be very useful. I've made it so in this list...
Should None just be a very special instance of Object? Does the Null type need to exist?
- If a file is opened in binary mode, should its iterator be over bytes instead of lines? Should "readline()" even work on a binary file?
Comparable: equals (Comparable) => Boolean Object (Comparable): hash () => Integer # presumably for "is" we compare the ids of the two objects id () => Comparable true () => Boolean # we rename __str__ to "printable_rendition" printable () => String class () => Type implements (Type) => Boolean getattr (String name) => Object setattr (String name, Object value) delattr (String name) => Object TypeSequence (Sequence): # sequence of Type objects Type (Object): name () => String # supertypes yields list of immediate parent types (what's in __bases__) supertypes () => TypeSequence # interfaces yields flattened list of all interface types this implements interfaces () => TypeSequence Null (Object): # according to the language reference manual, the Null type contains only one value, "None" None Exception (Object): args () => Sequence ExceptionContext (Object): exception () => Exception traceback () => Traceback Boolean (Object): True False Orderable: # according to Jim Jewett, only < is currently used for ordering less_than (Object) => Boolean Numeric: add (Numeric) => Numeric subtract (Numeric) => Numeric product (Numeric) => Numeric quotient (Numeric) => Numeric floored_quotient (Numeric) => Numeric remainder (Numeric) => Numeric negate (Numeric) => Numeric absolute_value () => Numeric exponentiate (Numeric) => Numeric magnitude () => Numeric Integer (Object, Orderable, Numeric): or (Integer) => Integer xor (Integer) => Integer and (Integer) => Integer shift (Integer) => Integer invert (Integer) => Integer real () => Real Real (Object, Orderable, Numeric): floor () => Integer ceiling () => Integer Complex (Object, Orderable, Numeric): conjugate () => Complex Decimal (Object, Orderable, Numeric): TBD Iterable: # let's rename __iter__ to "iterator" iterator () => Iteration StringIterable: # yields an iteration of String values KeyValueIterable (Iterable): # yields an iteration of key-value pairs Iteration (Object, Iterable): next () => Object # should Container be Iterable, or should that be reserved for real types, like Tuple? Container (Iterable): # we keep "len" as a mandatory method -- should we? And why isn't it "size"? len () => Integer contains (Object) => Boolean # we rename __getitem__ to "get" get (Object key) => Object MutableContainer (Container): # we rename __setitem__ to "add" # may quite easily raise KeyError when "key" is of the wrong type add (Object key, Object value) # we rename __delitem__ to "remove" remove (Object key) Set: is_subset (Set) => Boolean is_superset (Set) => Boolean union_with (Set) => Set intersection_with (Set) => Set difference (Set) => Set symmetric_difference (Set) => Set # should this be "multiply" to match Sequence? shallow_copy () => Set Sequence (Container): # this "contains" method looks for sub-sequences # how do we differentiate it from the Container method "contains()"? # should it be called "subsequence"? covers (Sequence) => Boolean # normal access via index # "end" defaults to start, "step" defaults to 1 slice (Integer start, Integer end = None, Integer step = None) => Sequence # return self + other Sequence concatenate (Sequence) => Sequence # N shallow copies of self multiply (Integer) => Sequence SequenceOfOrderable (Sequence): # do "min" and "max" make sense over arbitrary sequences? Should really only apply to sequences of "Orderable" min () => Orderable max () => Orderable MutableSequence (Sequence, MutableContainer): # append just calls "add(len(self), Object)" append (Object) => self # value at I is replaced with Object replace (Object, Integer position) => self # slice from I to J is replaced with values of Iterator replace (Iterable, Integer start, Integer end, Integer step = 1) => self extend (Object) => self count (Object) => Integer reverse () index (Object, Integer start = 0, Integer end = len(self)) => Integer pop (Integer position = 0) => Object push (Object, Integer position = 0) => self delete (Integer start, Integer end = start, Integer step = 1) => self sort (Function comparison_fn = None, Function key_fn = None, Boolean reverse = False) => self ByteSequence (Object, Sequence): # should this be a MutableSequence? Buffer (Object, MutableSequence): # is this just mutable version of ByteSequence? String (Object, Sequence): TBD Tuple (Object, Sequence): List (Object, MutableSequence): Mapping: # extra version of "get" which takes a default value get (Object key, Object default = None) => Object # should delete return the deleted value? Why not. That removes the need for "pop". delete (Object key) => Object clear () # shallow copy of mapping shallow_copy () => Mapping contains (Object key) => Boolean # items returns a value which is guaranteed to satisfy both the Set interface and the KeyValueIterable interface items () => (Set and KeyValueIterable) keys () => Set values () => Set # get_or_set is the current "setdefault" get_or_set (Object key, Object value) => Object update (Mapping) => self # alternate form of "update" takes Iterable of key-value pairs update (KeyValueIterable) => self # yet another form takes no positional parameters, and arbitrary keyword arguments # I need a notation for this kind of method update (KWDS) => self # do we really need fromkeys? fromkeys (Sequence keys, Object initial_value) => Mapping Dict (Object, Mapping, MutableContainer): # should some methods (e.g., "fromkeys") be here instead of in Mapping? ExecutionContext: enter () => ExecutionContext exit (ExceptionContext) => Boolean Stream: close () RandomAccessStream: # do we really need to continue to mimic the low-level UNIX seek and tell? # why not use Python sequence-style indices for offset? Positive int for relative # to start, negative int for relative to end, and just call tell() and add an offset # if you want to seek relative to the current location, for heaven's sake. seek (Integer offset) tell () => Integer BinaryInputStream (Stream): # read tries to read the whole file, but may return just a part of it read () => ByteSequence read (Integer) => ByteSequence OutputStream (Stream): flush() BinaryOutputStream (OutputStream): write (ByteSequence) => Integer TextStream: encoding () => String TextOutputStream (OutputStream, TextStream): writeline (String) => Boolean writelines (StringIterable) => Boolean TextInputStream (Stream, TextStream) readline () => String readlines () => StringIterable DiskFile (RandomAccessStream): fileno () => Integer filename () => String isatty () => Boolean truncate (Integer size) mode () => String # It would be nice to have another method, "mimetype", which would try to guess # the MIME type for the file, and if it can it would return two strings, the MIME major # type and minor type for the file. It would return None, None if it couldn't figure it out. # I'd suggest UNIX implementation just use "file", while Windows implementations # use registry and file extensions. # something like: mimetype () => String, String