UserDict's has_key() and get() should use __getitem__()
Andrew Dalke
dalke at acm.org
Wed Apr 5 18:11:45 EDT 2000
Hamish Lawson wrote:
>I grant that my proposal is a bit less efficient, but I see that
>as part of the cost for the proper abstraction. Given that
>UserDict exists primarily to be subclassed, and usually for the
>purpose of providing new definitions of setting and getting
>items, I do think that UserDict should be implemented in such a
>way as not to require those methods which are conceptually
>dependent to be redefined in the derived class.
I don't believe your estimate, that UserDicts are usually derived
"for the purpose of providing new definitions of setting and
getting items", is correct.
Most of the times I've used UserDict/UserList were to add extra
functionality. For example, a UserDict which preserves the
input order (modifies __setitem__ and keys; __delitem__ and
items/values should be added, but just needed a quick hack).
Or the Dict is supposed to emulate a dictionary-like format,
so I've had __str__ return the properly formatted string.
(Eg, consider a dictionary for HTML-like tags.)
Only rarely have it used it to do normalization - I try to
push that into the I/O routines.
In addition, in a good OO design, you should be able to use
an instance of a derived class anywhere you use an instance
of a base class. Your example (a caseless Dict), changes
how/when lookup failures occur. Thus, a "CaselessDict" really
isn't a type of UserDict, you're just using it for some
implementation reuse.
Instead, you want a minimal interface, which puts the least
amount of assumptions on the class as possible. This corresponds
to something like:
class AbstractUserDict:
...
def __getitem__(self, key):
raise NotImplementedError
def __setitem__(self, key, val):
raise NotImplementedError
def keys(self):
raise NotImplemenetedError
def has_key(self, key):
try:
self[key]
return 1
except KeyError:
return 0
def items(self):
items = []
for key in self.keys():
items.append(self[key])
return tuple(items)
...
Then Python's UserDict is just an implementation of the
AbstractUserDict base class.
This is the sort of design you need in a stricter compile-time
language like Java or C++. Because this is Python, you don't
need to tell the complier you're implementing an interface -
you just implement it. And because this is Python, it's easy to
implement.
Andrew
dalke at acm.org
More information about the Python-list
mailing list