d3pd
d3pd

Reputation: 8315

How should data attributes of a class be used as default arguments in methods of the class?

Let's say I want to set the default value of an argument of a method of a class to the value of some data attribute of the class. What is an appropriate way to do this? Is there a way to do this using lambda functions?

Here is some example code:

class A(object):

    def __init__(
        self
        ):
        self._defaultReportText = "hello world"

    def report(
        self,
        text = self._defaultReportText
        ):
        return(text)

Obviously, the default value specification for the argument text of the method report does not work here because self is not defined at this point. How should I make this value available?

Upvotes: 2

Views: 136

Answers (3)

mhawke
mhawke

Reputation: 87124

An alternative to using a special value such as None is to use a class variable:

class A(object):
    _defaultReportText = "hello world"

    def report(self, text=_defaultReportText):
        return text

Upvotes: -1

Roberto
Roberto

Reputation: 2786

If I understood your question, I usually do it with:

def report(self, text = None):
    if text is None:
        text = self._defaultReportText
    return(text)

(Edit: changed if not text to if text is None after Warren Weckesser's suggestion.)

Upvotes: 7

Martijn Pieters
Martijn Pieters

Reputation: 1123420

You cannot set the default value at class definition time, since defaults are stored with the function object, so no instances are available yet to take the default from.

Instead, use a sentinel, a unique value that you can easily test for. Usually this is None:

class A(object):
    def __init__(self):
        self._defaultReportText = "hello world"

    def report(self, text=None):
        if text is None:
            text = self._defaultReportText
        return text

If no text argument was supplied, it defaults to None and that can easily be tested for.

If None should be a possible value (e.g. you want to be able to use A().report(None) and that would behave differently from A().report(), then you'll have to pick a different sentinel. In that case use a unique instance of object() to test against:

_sentinel = object()


class A(object):
    def __init__(self):
        self._defaultReportText = "hello world"

    def report(self, text=_sentinel):
        if text is _sentinel:
            text = self._defaultReportText
        return text

Upvotes: 4

Related Questions