7

While assigning num1 = self.var1 in function fiz, Python says unresolved reference. Why is that?

class Foo:

    def __init__(self):
        self.var1 = "xyz"

    def fiz(self, num1=self.var1):
        return
CYAN CEVI
  • 813
  • 1
  • 9
  • 19
  • 3
    Default values cannot refer to other parameters, including `self`, as they are "not in the same scope". In fact, the values are resolved *before* the method is ever run. This is also why `def f(my_list = [])` does *not* create a new list each invocation.. one way to approach this would be to use `def fiz(self, num1 = None): if num1 is None: num1 = self.var1..` If there is a difference between 'None' and 'not specified', kwargs an be used. – user2864740 Jun 30 '16 at 07:26
  • `self` is not in scope inside the class defintion - you can't have an instance before you've finished defining the class! Just use `None` as a default, then set `num1 = self.var1 if num1 is None else num1` inside the method. – jonrsharpe Jun 30 '16 at 07:29

1 Answers1

7

Method (and function) default parameter values are resolved when the method is defined. This leads to a common Python gotcha when those values are mutable: "Least Astonishment" and the Mutable Default Argument

In your case, there is no self available when the method is defined (and if there was such a name in scope, as you haven't actually finished defining the class Foo yet, it wouldn't be a Foo instance!) You can't refer to the class by name inside the definition either; referring to Foo would also cause a NameError: Can I use a class attribute as a default value for an instance method?

Instead, the common approach is to use None as a placeholder, then assign the default value inside the method body:

def fiz(self, num1=None):
    if num1 is None:
        num1 = self.val1
    ...
Community
  • 1
  • 1
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • 1
    @BillalBEGUERADJ because I initially didn't find a duplicate, so wrote an answer, then thought of another search term I could use and managed to find one. And now I can't delete this answer, because it's accepted. – jonrsharpe Jun 30 '16 at 07:44
  • fair enough, have a nice day +1 – Billal Begueradj Jun 30 '16 at 07:45
  • Why is it possible to reference self in the functions attributes, but not as a default value of one of them? – Hedwin Bonnavaud Apr 25 '22 at 12:44
  • @HedwinBonnavaud I'm not sure what you're trying to ask, I don't know what _"reference self in the functions attributes"_ means. – jonrsharpe Apr 25 '22 at 12:51
  • I mean that the first word after the open parenthesis is "self". How is it possible if "there is no 'self' available when the method is defined"? – Hedwin Bonnavaud Apr 25 '22 at 12:53
  • 1
    @HedwinBonnavaud that's not _referencing_ it, it's _defining_ it. It doesn't have a _value_ to reference until the function gets _called_. – jonrsharpe Apr 25 '22 at 12:54
  • 1
    (Also note those are _parameters_, not _attributes_ @HedwinBonnavaud. Function objects can have attributes too, but that's not what we're talking about.) – jonrsharpe Apr 25 '22 at 13:03