inheriting variables

Alex Martelli aleax at aleax.it
Thu Apr 17 13:35:39 EDT 2003


Haran Shivanan wrote:

> module "Steve Holden" core dumped with the following output:
>> 
>>>>> class A:
>> ...   a = 0
>> ...   b = 1
>> ...
>>>>> class B(A):
>> ...   pass
>> ...
>>>>> b = B()
>>>>> A.a = 23
>>>>> b.a
>> 23
>>>>>
>> 
>> I suspect the OP wants a separate class variable for each subclass.
>> Right, Haran?
> Right.
> The variables in the subclass should not be bound to the parent.
> Any ideas?

Then you need to explicitly request copies.  What runs when B is
*created* (as opposed to, when B is *instantiated*) is the
initializer of B's metaclass, so to get non-standard behavior at
class-creation time you need a custom metaclass (which in practice
means your B class will be close to a new-style class, because
subclassing type is far and away the sensible way to get custom
metaclasses) -- might as well stick it in A, as long as you're
at it, so all descendants of A will automatically inherit it.

Basically, you want to re-bind (to the same name, and to a shallow
copy of the value, but in B itself) all the attributes of (direct?) 
base classes that are neither special (magical names) nor private 
(name starts with underscore) nor callable (if the exact condition 
you want to apply is different, adjust the following code, of course).

So, for example, and assuming you don't care about supporting 
multiple inheritance or only want the "copy behavior" from the 
one leftmost direct bast class if any:

import copy

class CopyingMeta(type):
    def __new__(metaclas, clasname, bases, clasdict):
        if bases:
            for n, v in vars(bases[0]).iteritems():
                if n in clasdict or n.startswith('_'
                    ) or callable(v): continue
                clasdict[n] = copy.copy(v)
        return type.__new__(metaclas, clasname, bases, clasdict)

class A:
    __metaclass__ = CopyingMeta
    a = 11
    b = 22

class B(A): pass

b = B()
A.a = 23
print b.a


This prints 11, as apparently required by your specs.  I hope
this can help you make the custom metaclass you need to
implement your actual, exact specifications, of course.


Alex





More information about the Python-list mailing list