Are decorators really that different from metaclasses...
Andrew Durdin
adurdin at gmail.com
Thu Aug 26 21:32:12 EDT 2004
On Thu, 26 Aug 2004 20:54:22 -0400, Paul Morrow <pm_mon at yahoo.com> wrote:
>
> Sure the interpreter uses __getitem__, but you use it too, right? I
> mean, you don't need the interpreter to tell you whether instances of
> the following class can act like a dictionary, do you?
>
> class Foo:
> def __getitem__(self, x): pass
>
> No you don't. Nor do you need to pretend that you're the interpreter,
> and simulate a call to an instance of Foo. That's because the mere
> presence of def __getitem__ tells you what you need to know. In this
> way, __getitem__ *does* serve as a declaration (of dictionary semantics)
> [*] to you and anyone reading your code.
That's because the dictionary interface/protocol requires a
__getitem__ method; there's no magical/technical reason why it should
be called __getitem__ rather than, say, dict_get_item.
As an example, the iterator protocol requires two methods: __iter__()
and next() -- the second doesn't have the double underscores, yet
still allows you to do:
class Foo:
def __iter__(self):
return self
def next(self):
return 42
for v in Foo():
print v
(yes, that's an infinite loop, but that's irrelevant). All the "magic"
__X__ methods are just those methods required by certain built-in
interfaces/protocols. And there's syntactic sugar to make them
convenient. They don't affect the creation of the class at all, as you
can (if necessary) add them in after the fact:
>>> class Foo:
... pass
...
>>> for i in Foo():
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: iteration over non-sequence
>>> def bar(self):
... return self
...
>>> def baz(self):
... raise StopIteration()
...
>>> Foo.__iter__ = bar
>>> Foo.next = baz
>>> for i in Foo():
... pass
...
>>>
More information about the Python-list
mailing list