An alternative approach to bound methods

Alex Martelli aleaxit at yahoo.com
Fri Feb 23 06:33:00 EST 2001


"Marcin 'Qrczak' Kowalczyk" <qrczak at knm.org.pl> wrote in message
news:slrn99ap97.lm7.qrczak at qrnik.zagroda...
> Thu, 22 Feb 2001 17:30:24 +0100, Alex Martelli <aleaxit at yahoo.com> pisze:
>
> > Where do you read/infer the limitation to *class* methods?
>
> My proposal doesn't change how instance methods and instance attributes
> can be used. Only class attributes change.
>
> Or I didn't understand what you mean?

Let's say we have...:

class Aclass:
    def amethod(x, *args):
        # body snipped

is this 'amethod' a "class method" or an "instance method"?  Does
calling it via

    x=Aclass();x.amethod(y,z)

or via

    x=Aclass();Aclass.amethod(x,y,z)

change anything?


> > But how does a given function, whose def is inside a class, know
> > whether it's supposed to recurse through its (potential) overrider
> > (via a same-name method of the first argument) or by defeating the
> > override (via its bare name, or, equivalently if your proposal was
> > adopted, using itself as an attribute in its enclosing class)?
>
> Are you asking what should one choose when he is writing the class?
> I don't know any case where it should recurse through its potential
> overrider yet, but perhaps they exist. This question can't have a
> general answer, similarly as questions like 'which class should I
> make an instance of here'.
>
> Are you asking about the semantics of a particular piece of code?
> If so, which code? My proposal is unambiguous.

And it does unambiguously mean that mentioning 'amethod' within
the above amethod's code body will in fact refer to Aclass.amethod,
not self.amethod, then?

In which case, the key objection is one I already raised, that
this is designed to make the easiest/most natural expression
the one for the case one wants *most rarely*.  People will often
and erroneously make recursive calls to "amethod(a,b,c)" when
they should be going through self, because "going through self"
IS the normal, most frequently desired case.

If you mean other things, then I have already expressed most
of my other objections.


> > Recursion apart, what distinguishes, e.g., a method foo in class
> > Derived(Base), calling the version it overrides as Base.foo(self,x,y),
> > and a "class-method" bar calling the same-name class-method of
> > the base class as Base.bar(x,y,z)?
>
> Technically nothing.
>
> Ideologically foo is an instance method, and bar is a class method,
> i.e. the first argument of foo is supposed to be an instance of a
> subclass of Base (even Derived at this usage point).

And this is checked at runtime, and gives a very clear
error message if the user makes a mistake about it:

TypeError: unbound method must be called with class instance 1st argument

I don't want to lose this very helpful error, and error
message, pursuing some kind of "ideological" target.
Practicality beats purity.

If "class methods" must exist (and I, for one, feel quite
happy without them), then they'd have to be distinguished
"technically" (in a compiler-visible way) from instance
methods, to cover the pragmatical need for clear messages
when programming errors are made.

class Base:
    def foo(self, *args):
        print "Base.foo",args

class Derived(Base):
    def foo(self, *args):
        print "Derived.foo",args
        Base.foo(*args)

I don't want this error to become a silent, mysterious
one; we know have clear diagnostics for it, and losing
them would be a serious step backwards.


Alex







More information about the Python-list mailing list