Is there a way to 'mask out' inherited methods?

Steve Holden sholden at holdenweb.com
Sat May 4 01:05:05 EDT 2002


"Ralf Juengling" <juenglin at informatik.uni-freiburg.de> wrote ...
[martellibot wisdom snipped]
>
> Thanks for your answers (to all of you).
>
> I still have problems to get the right picture about
> instance attributes. At first I thought, anything is
> dynamic and 'bound methods' and 'data attributes' we're
> treated similar in that you can add and remove them
> at runtime if you like. Then one could sth like this:
>
> class A:
>
>     def __init__(self):
>         pass
>
>     def mA(self):
>         print "Here I am."
>
According to this definition, mA is an atribute of the A class (the action
of the def statement is to bind the code body to the name in the
currently-active local scope, which is that of the class).

> class B(A):
>
>     def __init__(self):
>         A.__init__self)
>         del self.mA
>
Aha! You are getting confused because the A.mA method/attribute is available
as B.mA by inheritance, and therefore is also available as an instance
method in instances of B. However, the mechanism that makes it available is
a complex search of a sequence on namespaces (the instance, the instance's
class, the instance's class's superclass, ...).

To make things still more confusing, if a method binds a name qualified by
self (such as self.mA) then that creates a binding of the attribute name
local to the instance in which the code is performed. You can verify this by
changing the definition of A so its __init__() binds to an instance variable
with a simple assignment like

        self.instancevar = 1

Because this name is bound in the instance's namespace when a B is created
(even though the binding is performed by a method defined in and inherited
from A) there will be no problem if the B.__init__() method performs

        del self.instancevar

>     def mB(self):
>         print "Me too."
>
>
> This doesn't work; I get:
>
> >>> b = B()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "vector1.py", line 47, in __init__
>     del self.mA
> AttributeError: B instance has no attribute 'mA'
>
>
Well, hopefully you now at least understand why. Namespaces are a crucial
concept in Python, and if you aren't used to quite such a dynamic
environemtn, or if you are new to late-bound object-oriented programming, it
can all get a little bit confusing.

> Okay. Just to try, I changed A to a new-style class
> (class A(object): ). In this case I get:
>
> >>> b = B()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "vector1.py", line 47, in __init__
>     del self.mA
> AttributeError: 'B' object attribute 'mA' is read-only
>
> So, what's that?
>
Well I'm only going to put a toe in this water, as this stuff is pretty new.
Alex can set you straight is necessary. New-style classes appear (from this
error message :-) to bind method names much more rigidly than classis
classes. They are therefore not amenable to the same naughty games you could
classically play with your classes and objects.

> I've already heard that the 'attribute resolving-' or
> 'attribute access-'methodology changed in 2.2, i.e.
> there are now special 'descriptor objects' for that
> purpose. However, I don't understand what's going on.
>
Me neither. Where is Alex when you need him? <wink>

> What happens -- in terms of descriptors -- when the
> following expressions are evaluated? (Imagine the del
> statement in B.__init__ is absent and):
>
> b = B()
>
> 1. b.mA()

The mA() method inherited from A is called as described above, with b as its
first argument.

> 2. b.mB()

The B.mB() method is called, with b as its first argument.

>
> 3. b.mA = 'eat that'

New-style: nono. Classic: binds an instance-local "mA" attribute to the
string. This attribute masks the mA inherited from the class's superclass,
since the search willl now be satisfied by the instance's local namespace.

> 4. b.mB = 'or that'

Same as for 3, except that the name that is masked is defined in the
instance's class definition.

>
> 5. del b.mA
> 6. del b.mB
>
Do you mean after 1-4, or independently of them? Seriously, I would hope you
could work that out for yourself by now. If not, please feel free to post
again.

regards
 Steve
--

Steve Holden: http://www.holdenweb.com/ ; Python Web Programming:
http://pydish.holdenweb.com/pwp/








More information about the Python-list mailing list