instance/class methods: having my cake and eating it too

Donnal Walter donnal at donnal.net
Thu Aug 29 07:28:14 EDT 2002


To enforce 'encapsulation' of a class attribute, I would like to
define a class method that sets that class attribute (format):

class Decimal:

    format = '%.0f'   # default format is for integer printing

    def GetFormat(self):
        return self.format

    def SeeFormat(self):
        print self.GetFormat()

    def SetDigits(cls, digits):
        digits = min(digits, 5)
        cls.format = "%%.%uf" % digits

    SetDigits = classmethod(SetDigits)

class Weight(Decimal):

    Decimal.SetDigits(3)

>>> x = Weight()
>>> x.SeeFormat()
%.3f

But I also want to be able to override this class attribute with an
instance attribute that is set using an instance method:

    def InstanceSetDigits(self, digits):
        digits = min(digits, 5)
        self.format = "%%.%uf" % digits

class MyContainer:

    def __init__(self):
        self.wt = Weight()
        self.wt.InstanceSetDigits(2)

>>> y = MyContainer()
>>> y.wt.SeeFormat()
%.2f

This works, but having both SetDigits and InstanceSetDigits is
redundant code and makes for a confusing API. Is there any way I can
define ONE method that works like a class method when called from the
base class object and like an instance method when called from an
instance?



More information about the Python-list mailing list