On Friday, February 8, 2013 11:48:43 AM UTC-6, Rick Johnson wrote: > > [...] > > So using a /real/ OOP paridigm we would do the following: > > ## START TRUE OOP PARIDIGM ## > > [...snip naive example...]
Actually my example API is littered with artifacts of a python "global function architecture". In a /true/ 100% OOP language most of these "dunder" methods would become interface members of the object. There is also the question of WHEN to use and WHEN NOT to use the "dunder" naming convention. I actually like the convention myself for clearly defining methods that are called by "syntactic sugar". However, python employs the convention quite haphazardly. For example: __iadd__ is called by an expression such as: "1+=1" which is translated into: "1.__iadd__(1)" However: __repr__ is called by the the global "repr" function which is translated into: "obj.__repr__()" I don't like the second usage because i believe this naming convention should be reserved for syntactical sugar only. But i digress... Here is a better example of Python converted into true OOP paridigm (renaming and removing methods appropriately to fit my logical 100% OOP API). class Object(SuperType): def construct # aka: __init__ def desconstruct # aka: __del__ def class def delattr(name) def doc def getattr(name) def __new__ # dunder??? def repr def setattr(name, value) def size def stringify # aka: __str__ def subclasshook # XXX: dunder??? def true? # aka: __bool__ def callable? def compare(other) def methods def instance_methods def hash def help def id def isinstance?(this) def issubclass?(this) def super def type class SequenceBase(Object): # Methods from object are free def __add__ def __contains?__ def __delitem__ def __delslice__ def __eq__ def __ge__ def __getitem__ def __getslice__ def __gt__ def __iadd__ def __imul__ def __iter__ def __le__ def __lt__ def __mul__ def __ne__ def __rmul__ def __setitem__ def __setslice__ # # Interface # slice = __getslice__ extend = __add__ contains? = __contains?__ def length # pka: __len__ def any def all def enumerate -> iterator def filter(proc) def map(proc) def max def min def reverse def reduce(proc) def sort def zip class Sequence(SequenceBase): # aka: list # Methods from SequenceBase and Object are free! # # Interface # def append(this) def count(this) def index(this) def insert(idx, this) def pop() def remove(this) def reverse def sort I'm a bit unnerved by the sum function. Summing a sequence only makes sense if the sequence in question contains /only/ numeric types. For that reason i decided to create a special type for holding Numerics. This will probably result in many complaints from lazy people who want to use only one Sequence type, which holds mixed types, THEN jamb nothing but numeric types into it, THEN have a sum method that throws errors when it encounters a non-numeric type!!! I say, too bad for you. Stop obfuscating your code! Of course someone could probably find a legitimate reason to apply a sum method to non-numeric values; if so, then inherit from NumericSequence and create your custom type! class NumericSequence(Sequence): # Methods from Sequence, SequenceBase, and Object are free! def __setitem__(item): if not item.isinstance(Numeric): raise TypeError() def __add__(other): if not other.isinstance(NumericSequence): raise TypeError() def __setslice__(other): # blah # # Interface # def sum -> Integer -- http://mail.python.org/mailman/listinfo/python-list