Differences between revisions 9 and 10
Revision 9 as of 2006-11-29 00:06:12
Size: 4586
Editor: reflux
Comment: raised some questions about the Py2K type hierarchy
Revision 10 as of 2006-11-29 00:52:52
Size: 6676
Editor: reflux
Comment: add more types
Deletions are marked like this. Additions are marked like this.
Line 9: Line 9:
 * In Py2, Boolean is a sub-type of Integer. Does this make sense? I've made it its own type in this list...
 * Should None just be an instance of Object? Does NoneType need to exist?
 * In Py2, {{{Boolean}}} is a sub-type of Integer. Does this make sense? I've made it its own type in this list...
 * Should {{{None}}} just be an instance of {{{Object}}}? Does {{{NoneType}}} 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?
Line 28: Line 29:
NoneType (Object): Null (Object):
Line 75: Line 76:

KeyValueIterable (Iterable):
 # yields iteration of key-value pairs
Line 142: Line 146:
List (Object, Comparable, MutableSequence): List (Object, MutableSequence):

Mapping:
 get (Object key) => Object
 get_with_default (Object key, Object default) => Object
 set (Object key, Object value)
 # should delete return the deleted value? Why not. That removes the need for "pop".
 delete (Object key) => Object
 clear ()
 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
 # do we really need fromkeys?
 fromkeys (Sequence keys, Object initial_value) => Mapping

Dict (Object, Mapping, Container):
 # should some methods (e.g., "fromkeys") be here instead of in Mapping?

ExecutionContext:
 enter () => ExecutionContext
 exit (ExceptionContext) => Boolean

Stream:
 close ()
 flush ()
 read () => ByteSequence
 read (Integer) => ByteSequence
 write (ByteSequence) => Integer

RandomAccessStream (Stream):
 # do we really need to continue to mimic the low-level UNIX seek and tell?
 # why not use Python sequence-style indices for offset?
 seek (Integer offset)
 tell () => Integer

TextStream (Stream):
 readline () => String
 readlines () => Sequence
 writeline (String) => Boolean
 writelines (Sequence) => Boolean
 codeset_name () => String

OpenFile (RandomAccessStream):
 # it would be great if this had a "mimetype" method
 fileno () => Integer
 filename () => String
 isatty () => Boolean
 truncate (Integer size)
 
BinaryOpenFile (Object, Stream, OpenFile, Iterable, ExecutionContext):

TextOpenFile (Object, TextStream, OpenFile, Iterable, ExecutionContext):

Possible Python 3K Class Tree?

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 parameters, such as in the "sort" method on MutableSequence?

  • 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)?

  • 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...

  • In Py2, Boolean is a sub-type of Integer. Does this make sense? I've made it its own type in this list...

  • Should None just be an instance of Object? Does NoneType 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
 # presumable for "is" we compare the ids of the two objects
 id () => Integer
 true () => Boolean
 # the __str__ method
 printable () => String

Ellipsis (Object):
 # contains only the single value represented by three dots
 ThreeDots

Null (Object):
 # only a single value of this type
 None

Boolean (Object):
 True
 False

Orderable:
 less_than (Object) => Boolean
 greater_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:
 iterator () => Iteration

Iteration (Object, Iterable):
 next () => other

KeyValueIterable (Iterable):
 # yields iteration of key-value pairs 

# should Container be Iterable, or should that be reserved for real types, like Tuple?
Container (Iterable):
 len () => Integer
 contains (Object) => Boolean

Set (Container):
 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):
 contains (Sequence) => Sequence
 # normal access via index
 slice1 (Integer) => Object
 # normal slice of range
 slice2 (Integer, Integer) => Sequence
 # slice with step K
 slice3 (Integer, Integer, Integer) => Sequence
 # return self + other Sequence
 concatenate (Sequence) => Sequence
 # N shallow copies of self
 multiply (Integer) => Sequence
 # do "min" and "max" make sense over arbitrary sequences?  Should really only apply to sequences of "Orderable"
 min () => Object
 max () => Object

MutableSequence (Sequence):
 append (Object) => self
 insert (Integer position, Object) => self
 # value at I is replaced with Object
 replace (Integer position, Object) => self
 # slice from I to J is replaced with values of Iterator
 replace2 (Integer start, Integer end, Iterable) => self
 # slice from I to J with step K is replaced by Iterator
 replace3 (Integer start, Integer end, Integer step, Iterable) => self
 extend (Object) => self
 count (Object) => Integer
 reverse ()
 index1 (Object) => Integer
 index2 (Object, Integer start, Integer end) => Object
 pop1 () => Object
 pop2 (Integer position) => Object
 delete1 (Integer position) => self
 delete2 (Integer start, Integer end) => self
 delete3 (Integer start, Integer end, Integer step) => self
 sort0 () => self
 sort1 (Function comparison_fn) => self
 sort2 (Function comparison_fn, Function key_fn) => self
 sort3 (Function comparison_fn, Function key_fn, Boolean reverse) => 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:
 get (Object key) => Object
 get_with_default (Object key, Object default) => Object
 set (Object key, Object value)
 # should delete return the deleted value?  Why not.  That removes the need for "pop".
 delete (Object key) => Object
 clear ()
 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
 # do we really need fromkeys?
 fromkeys (Sequence keys, Object initial_value) => Mapping

Dict (Object, Mapping, Container):
 # should some methods (e.g., "fromkeys") be here instead of in Mapping?

ExecutionContext:
 enter () => ExecutionContext
 exit (ExceptionContext) => Boolean

Stream:
 close ()
 flush ()
 read () => ByteSequence
 read (Integer) => ByteSequence
 write (ByteSequence) => Integer

RandomAccessStream (Stream):
 # do we really need to continue to mimic the low-level UNIX seek and tell?
 # why not use Python sequence-style indices for offset?
 seek (Integer offset)
 tell () => Integer

TextStream (Stream):
 readline () => String
 readlines () => Sequence
 writeline (String) => Boolean
 writelines (Sequence) => Boolean
 codeset_name () => String

OpenFile (RandomAccessStream):
 # it would be great if this had a "mimetype" method
 fileno () => Integer
 filename () => String
 isatty () => Boolean
 truncate (Integer size)
 
BinaryOpenFile (Object, Stream, OpenFile, Iterable, ExecutionContext):

TextOpenFile (Object, TextStream, OpenFile, Iterable, ExecutionContext):


CategoryLanguage

AbstractBaseClasses (last edited 2008-11-15 13:59:38 by localhost)

Unable to edit the page? See the FrontPage for instructions.