Python Module Exposure
Jacob Page
apoco at cox.net
Sat Jul 9 05:53:42 EDT 2005
George Sakkis wrote:
> 1. As already noted, ISet is not really descriptive of what the class
> does. How about RangeSet ? It's not that long and I find it pretty
> descriptive. In this case, it would be a good idea to change Interval
> to Range to make the association easier.
The reason I decided not to use the term Range was because that could be
confused with the range function, which produces a discrete set of
integers. Interval isn't a term used in the standard/built-in library,
AFAIK, so I may stick with it. Is this sound reasoning?
> 2. The module's "helper functions" -- which are usually called factory
> functions/methods because they are essentially alternative constructors
> of ISets -- would perhaps better be defined as classmethods of ISet;
> that's a common way to define instance factories in python. Except for
> 'eq' and 'ne', the rest define an ISet of a single Interval, so they
> would rather be classmethods of Interval. Also the function names could
> take some improvement; at the very least they should not be 2-letter
> abbreviations. Finally I would omit 'eq', an "interval" of a single
> value; single values can be given in ISet's constructor anyway. Here's
> a different layout:
First, as far as having the factory functions create Interval instances
(Range instances in your examples), I was hoping to avoid Intervals
being publically "exposed." I think it's cleaner if the end-programmer
only has to deal with one object interface.
I like the idea of lengthening the factory function names, but I'm not
sure that the factory methods would be better as class methods.
Consider a use-case:
>>> import iset
>>> interval = iset.ISet.lowerThan(4)
as opposed to:
>>> import iset
>>> interval = iset.lowerThan(4)
This is less typing and probably eliminates some run-time overhead. Can
you list any advantages of making the factory functions class methods?
> class Range(object): # Interval
>
> @classmethod
> def lowerThan(cls, value, closed=False):
> # lt, for closed==False
> # le, for closed==True
> return cls(None, False, value, closed)
>
> @classmethod
> def greaterThan(cls, value, closed=False):
> # gt, for closed==False
> # ge, for closed==True
> return cls(value, closed, None, False)
>
> @classmethod
> def between(cls, min, max, closed=False):
> # exInterval, for closed==False
> # incInterval, for closed==True
> return cls(min, closed, max, closed)
I like the function names, but in my dialect, lessThan would be more proper.
> class RangeSet(object): # ISet
>
> @classmethod
> def allExcept(cls, value): # ne
> return cls(Range.lowerThan(value), Range.greaterThan(value))
>
> 3. Having more than one names for the same thing is good to be avoided
> in general. So keep either "none" or "empty" (preferably "empty" to
> avoid confusion with None) and remove ISet.__add__ since it is synonym
> to ISet.__or__.
I agree that "none" should be removed. However, some programmers may
prefer to use +, some |, so I'd like to provide both.
> 4. Intervals shouldn't be comparable; the way __cmp__ works is
> arbitrary and not obvious.
I agree that __cmp__ is being used arbitrarily. I wanted sorting to be
easy, but there's other ways of doing that. I'll take your suggestion.
> 5. Interval.adjacentTo() could take an optional argument to control
> whether an endpoint is allowed to be in both ranges or not (e.g.
> whether (1,3], [3, 7] are adjacent or not).
Interval objects weren't meant to be public; adjacentTo is used by ISet
for combinatory functions. I could look into ways to hide the class
from the public, but hiding things never seemed Pythonic to me; someone
may want to use them for some reason. Maybe pydoc can be made to not
document certain objects.
> 6. Possible ideas in your TODO list:
> - Implement the whole interface of sets for ISet's so that a client
> can use either or them transparently.
That was my intention. I'll have to see which interface functions I'm
missing.
> - Add an ISet.remove() for removing elements, Intervals, ISets as
> complementary to ISet.append().
> - More generally, think about mutable vs immutable Intervals and
> ISets. The sets module in the standard library will give you a good
> idea of the relevant design and implementation issues.
Both good ideas.
> After I look into the module's internals, I'll try to make some changes
> and send it back to you for feedback.
Thanks for your feedback, George. I look forward to any additional
comments you come up with.
More information about the Python-list
mailing list