简体   繁体   中英

class variables in multi-inheritance python classes

I have a Base class that stores some basic methods, attributes, etc in it and I've got a Mixin that I'd like to share across one or more sub-classes of Base . Something like this:

class Base(object): pass

class Mixin(object):
    # IMPORTANT: cache _x locally on Mixin to only compute for all subclasses
    _x = None

    @property
    def x(self):
        if self._x is None:
            print 'reset _x'
            self._x = 2
        return self._x

class A(Base, Mixin): pass
class B(Base, Mixin): pass

Importantly, I want to cache the _x variable on the Mixin so it is only computed once across all subclasses A , B , etc. --- it takes a long time to compute this value. Oddly, this doesn't appear to work as I expected in python:

a = A()
b = B()
print 'calling a.x'
a.x
print 'calling a.x'
a.x
print 'calling b.x'
b.x
print 'calling b.x'
b.x

This prints out reset _x twice --- once for the first call to ax, which I expected, and again for the first call to bx, which I didn't expect. My understanding of python class attributes was that they are stored once on a per-class basis. Can anyone explain what is going on here?

Are there better patterns for having _x cached locally on Mixin ?

Your problem is that you're referencing self._x . This is an instance attribute, ie, it is different for every instance. If you haven't set self._x then Python uses the first _x found on classes in the inheritance hierarchy (which will be _x on your Mixin class), but as soon as you set self._x then _x will always be found on that instance. On a new instance, the attribute won't be set, so Mixin._x will be used, but it's always None because you never change it.

So you want to use Mixin._x everywhere you have self._x , but especially when setting that attribute.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM