0

For a method of a class I want the following behaviour

>>class A:
>>    def __init__(self, x):
>>        self.x = x
>>    def func(self, x = self.x):
>>        print(x)
>>a = A(5)
>>a.func(2)
2
>>a.func()
5

But I get this error for the declaration of func():

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in A
NameError: name 'self' is not defined

Is there a recommended way to achieve this behaviour?

Sahand
  • 6,046
  • 14
  • 51
  • 105

2 Answers2

3

Use a sentinel value; None typically suffices.

class A:
    def __init__(self, x):
        self.x = x
    def func(self, x=None):
        if x is None:
            x = self.x
        print(x)

If, for whatever reason, None could be a valid argument, you can create your own sentinel.

_sentinel = object()
class A:
    def __init__(self, x):
        self.x = x
    def func(self, x=_sentinel):
        if x is _sentinel:
            x = self.x
        print(x)
chepner
  • 389,128
  • 51
  • 403
  • 529
2

You cannot refer to self in a function declaration, since at that point self indeed doesn't exist (as the error says). The idiomatic way is:

def func(self, x = None):
    if x is None:
        x = self.x
    print(x)

Or perhaps:

def func(self, x = None):
    print(x or self.x)

(Though note that falsey isn't the same as None and may hence behave differently.)

deceze
  • 471,072
  • 76
  • 664
  • 811
  • Don't use `not`; what if x is 0 or false or an empty list or any other value that might be treated as False? You are specifically looking for the exact object `None`. – chepner Oct 16 '17 at 13:26
  • Hence my footnote. – deceze Oct 16 '17 at 13:26
  • Explaining why it is a bad idea doesn't really justify suggesting it in the first place. – chepner Oct 16 '17 at 13:29
  • Depending on what you expect valid inputs to this function to be and what behaviour it should display for invalid values, it may be entirely reasonable. – deceze Oct 16 '17 at 13:30
  • None of which is present in the question; you are making unwarranted assumptions. – chepner Oct 16 '17 at 13:46