How to define a default argument in __init__ of a class that uses a static class variable?

Viewed 501

I have an issue where I'm trying to use a static variable as a required named default argument in init of a class:

class Foo:
    bar = 1
    rab = 2
    
    def __init__(self, /, def_arg=Foo.bar):
        if def_arg == self.bar:
            pass
        elif def_arg == self.rab:
            pass

Foo()
Foo(Foo.rab)

4: NameError: name 'Foo' is not defined

I also tried without Foo. and also tried self. but it doesn't work. It has to be specifically static, so I don't want to use self.bar. Is this at all possible?

4 Answers

If you use only bar it works.

def __init__(self, def_arg=bar):
    print(def_arg)

You could probably do like this...

class Foo:
    bar = 1

    def __init__(self, def_arg=bar):
        self.def_arg = def_arg

    def __repr__(self):
        return "{self.def_arg}".format(self=self)

foo = Foo()
print(foo) # should print 1

Default keyword assignments are made when the method is compiled. That happens before the class has been assigned to Foo, so Foo.bar doesn't exist yet. But bar does exist in the enclosing namespace at this point. def_arg=bar will grab the current object in bar and make that the default argument for __init__. Note that once a default argument has been set, it can't be changed. If Foo.bar is reassigned, that doesn't affect the default value already placed in the function object for __init__.

class Foo:
    bar = 1
    rab = 2
    
    def __init__(self, def_arg=bar):
        if def_arg == self.bar:
            pass
        elif def_arg == self.rab:
            pass

Foo()
Foo(Foo.rab)

I think if you made a another func with the @classmethod decorator, you could use the variable as static, like so:

class Foo:
   bar = 1

   def __init__(self):
       print(self.func())
   @classmethod
   def func(cls):
       return cls.bar

bar will still be a static variable

Related