Adriaan
Adriaan

Reputation: 715

Delay an evaluation containing the key word self in Python

As a follow up question to

Delay an evaluation / lazy evaluation in Python

I would like to delay an evaluation containing the key word self in Python.

Minimum working example:

class TestClass:

    def __init__(self, variable_0):
        self.__variable_0 = variable_0

    def get_variable_0(self):
        return self.__variable_0

    def test_delayed_evaluation(self, delayed_evaluation):
        print(delayed_evaluation)


delayed_evaluation_0 = lambda: self.get_variable_0()
test_class = TestClass(3)
test_class.test_delayed_evaluation(delayed_evaluation_0)  # Returns <function <lambda> at 0x0000024E49DE66A8>.
test_class.test_delayed_evaluation(delayed_evaluation_0())  # Returns NameError: name 'self' is not defined.

I know this piece of code works when I replace self with test_class, but in the (other) code in the project I am working on, the class instance is not explicitly known, so I can't use that approach.

Why does Python not recognize self?

Upvotes: 0

Views: 88

Answers (1)

bufh
bufh

Reputation: 3420

I don't know what exactly you are trying to achieve (even reading the previous question); it would be good to have a better use-case.

Why does Python not recognize self?

Because it is not defined at the moment it is called; for your code you effectively could make it work with

delayed_evaluation_0 = lambda self: self.get_variable_0()
test_class.test_delayed_evaluation(delayed_evaluation_0(test_class))

I suppose what you want to do would be with something like:

class TestClass:
    def __init__(self, variable_0):
        self.__variable_0 = variable_0

    def get_variable_0(self):
        return self.__variable_0

    def test_delayed_evaluation(self, delayed_evaluation):
        return getattr(self, delayed_evaluation)()

    def test_delayed_evaluation_with_parameters(self, delayed_evaluation, *args, **kwargs):
        lazy_func = getattr(self, delayed_evaluation)
        return lazy_func(*args, **kwargs)


test_case = TestClass(3)
test_case.test_delayed_evaluation('get_variable_0')

You could also want to look at functools.partial to complement your knowledge on some use-cases which would be better implemented with it than with lambda.

Upvotes: 1

Related Questions