Skip to content Skip to sidebar Skip to footer

Default Argument Value From Overridden Method (preventing Boilerplate)

I have a base class Base and two sub classes Foo and Bar. In Base I define a function with an optional argument. This argument is either given or fetched at runtime (not at definit

Solution 1:

How about using a decorator? This is the sort of thing they are meant for. Something like:

def get_at_runtime(func):
    def wrapped(*args, **kwargs):
        if kwargs.get('name', None) is None:
            kwargs['name'] = get_name_at_runtime()
        func(*args, **kwargs)

and wrap your methods:

@get_at_runtime
def greet(self, name=None):
    print('Hello {name} this is Foo.'.format(name=name))

Solution 2:

Hi You can use metaclasses

class DefaultNameType(type):
    def __new__(cls, name, bases, attrs):
        if 'greet' in attrs:
            attrs['_greet'] = attrs.pop('greet')
            def greet(self, name=None):
                name = name or self.get_name_at_runtime()
                return self._greet(name)
            attrs['greet'] = greet
        print attrs
        return super(DefaultNameType, cls).__new__(cls, name, bases, attrs)

class Base(object):
    __metaclass__ = DefaultNameType

    def get_name_at_runtime(self):
        return 'foo'

    def greet(self, name):
        pass

class Foo(Base):
    def greet(self, name):
        print('Hello {name} this is Foo.'.format(name=name))

class Bar(Base):
    def greet(self, name):
        print('Hello {name} this is Bar.'.format(name=name))    

    def get_name_at_runtime(self):
        return 'foo1'

In this case any class derived from Base will be modified so that method greet will be renamed to _greet and greet method will be created which will run _greet


Post a Comment for "Default Argument Value From Overridden Method (preventing Boilerplate)"