Loveen Dyall
Loveen Dyall

Reputation: 834

python3 default class attribute to method in same class

class Test:
    func = self.func2 # default: func is func2 by default
    # tried Test.func2 as well and Pycharm shows error

    def __init__(self, func=None):
        if func is not None:
            self.func = func

    def func1(self):
        pass

    def func2(self):
        pass

Can anyone advise how to achieve something like the above?

I have tried setting the func parameter to default to func2 in the constructor too but this also errors.

so later, somewhere in the class Test, I can just call self.func instead of repeatedly running conditions to find out whether func1 or func2 should be used

self.func()

**** SOLUTION (what I did) ****

in the main.py:

t = Test(func=Test.func1)
t.func(t, **kwargs)

this should successfully call t.func1 (or t.func2 if specified) with access to the t instance_attributes through a call of higher order method t.func

Upvotes: 1

Views: 558

Answers (2)

Blckknght
Blckknght

Reputation: 104682

Your code doing an assignment at class scope would work if you don't use self (which isn't defined) and if you move it to the end of the class definitions, so that func2 will exist in the namespace when it runs.

class Test:
    def __init__(self, func=None):
        if func is not None:
            self.func = func

    def func1():
        pass

    def func2():
        pass

    func = func2 # this will work down here

I'd note that when you assign a function to a class variable, it's going to be treated like a method, so you might need to change func2 to expect self as its first argument. The binding behavior won't happen for methods assigned as instance variables, like any func passed in to the __init__ method. If you want binding behavior for those, you'd need to implement it yourself (perhaps with functools.partial).

Upvotes: 0

Reblochon Masque
Reblochon Masque

Reputation: 36652

You could set the default in the __init__ method, based on the value of the func parameter:

Maybe something like this:

class Test:

    def __init__(self, func=None):
        if func is None:
            self.func = self.func2
        else:
            self.func = func

    def func1():
        print('func1')

    def func2(self):
        print('func2')

Test().func()
Test(Test.func1).func()

output:

func2
func1

Upvotes: 1

Related Questions