How can I use `self` inside a function that is passed as a higher-order function to a method?

Question:

I am trying write a signal processing package, and I want to let user creates a custom function without needing to access the class file :

class myclass():
    def __init__(self):
        self.value = 6
    def custom(self, func, **kwargs):
        func(**kwargs)
        return self

c = myclass()
def add(**kwargs):
    self.value +=  kwargs['val']

kwargs = {'val': 4}
c.custom(add, **kwargs )
print (c.value)

I got name ‘self’ is not defined. Of course because func is not a method to the class. But I am not sure how to fix it. Please advice.

Thanks

Asked By: J_yang

||

Answers:

You can explicitly pass the self argument to add:

class myclass():
    def __init__(self):
        self.value = 6
    def custom(self, func, **kwargs):
        func(self, **kwargs)
        return self

c = myclass()
def add(self, **kwargs):
    self.value +=  kwargs['val']

kwargs = {'val': 4}
c.custom(add, **kwargs )
print (c.value)

Output:

10
Answered By: Cloudomation

You need to pass the class instance into the method too,
do this :

class myclass():
    def __init__(self):
        self.value = 6
    def custom(self, func, **kwargs):
        func(self, **kwargs) ## added self here
        return self

c = myclass()
def add(self, **kwargs):  ## added self here
    self.value +=  kwargs['val']

kwargs = {'val': 4}
c.custom(add, **kwargs )
print (c.value)

output : 10

Answered By: Mohamed Benkedadra

I would do one of the following:

1) Make the custom method a method of the class.

class myclass():
    def __init__(self):
        self.value = 6
    def custom(self, func, **kwargs):
        func(**kwargs)
        return self
    def add(self, **kwargs):
        self.value +=  kwargs['val']

kwargs = {'val': 4}
c = myclass()
c.custom( c.add, **kwargs )
print (c.value)    # Result == 10

2) Do not give the custom value itself access to class variables.

class myclass():
    def __init__(self):
        self.value = 6
    def custom(self, func, **kwargs):
        self.value += func(**kwargs)
        return self


def add(**kwargs):
    return kwargs['val']

kwargs = {'val': 4}
c = myclass()
c.custom(add, **kwargs )
print (c.value)    # Result == 10
Answered By: DaWhiteSheep
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.