TransWikia.com

Return from __call__ immediately if a value gets changed in the class

Stack Overflow Asked by Raksha B on December 30, 2020

I want to return to the main function whenever value of a is set to 1 by any of the functions(func1,func2,func3) called in the class. Can anyone help me in solving this?I need to return immediately before calling rest of the functions when value is set. I have attached a code snippet for reference.


    class Property:
    
        def __init__(self):
            ## initializing the attribute
            self.a = 0
        def __call__(self, val):
            self.func1(val)
            self.func2(val)
            self.func3(val)
        def func1(self,value):
            if value==20:
                self.a = 1
                return
            print("all okay in func1")
        def func2(self,value):
            if value==40:
               self.a = 1
               return
            print("all okay in func2")
        def func3(self,value):
            if value==60:
               self.a = 1
               return
            print("all okay in func3")
     
     def main():            
         obj = Property()
         obj(20)

2 Answers

In contrast to my other answer @Copperfield had the suggestion of using the Python @property decorators to do this, which could be handy for some applications. This saves you from having to changing the code where you assign self.a = 1, and it will just "automatically" notice whenever you happen to make such an assignment. It's a bit more "under the hood", i.e. less transparent to readers of the code, but could still be useful:

class Property:

    def __init__(self):
        ## initializing the attribute (Note change to _a, not a)
        self._a = 0
    def __call__(self, val):
        try:
            self.func1(val)
            self.func2(val)
            self.func3(val)
        except MyCustomException:
            return
    def func1(self,value):
        if value==20:
            self.a = 1
        print("all okay in func1")
    def func2(self,value):
        if value==40:
           self.a = 1
        print("all okay in func2")
    def func3(self,value):
        if value==60:
           self.a = 1
        print("all okay in func3")

    @property
    def a(self):
        return self._a

    @a.setter
    def a(self, new_value):
        self._a = new_value
        if self._a == 1:
            throw MyCustomException

What is happening here is that we have specified a as a property. On the surface it works just like a normal member variable in how you assign and access it, however with the special @a.setter decorator we can define a custom function that runs whenever you set its value. So here we can make it check what value is being assigned, and throw a MyCustomException if that value is 1, which we can then catch after skipping the functions that you didn't want to run.

Answered by Ben Farmer on December 30, 2020

How's this?

class Property:

    def __init__(self):
        ## initializing the attribute
        self.a = 0
    def set_a_to_1_and_raise(self):
        self.a = 1
        throw MyCustomException 
    def __call__(self, val):
        try:
            self.func1(val)
            self.func2(val)
            self.func3(val)
        except MyCustomException:
            return
    def func1(self,value):
        if value==20:
            self.set_a_to_1_and_raise()
        print("all okay in func1")
    def func2(self,value):
        if value==40:
           self.set_a_to_1_and_raise()
        print("all okay in func2")
    def func3(self,value):
        if value==60:
           self.set_a_to_1_and_raise()
        print("all okay in func3")

Edit: Added @tdelaney's nice suggestion regarding the name of the function self.set_a_to_1_and_raise() to make it obvious that it raises an exception when you call it.

Answered by Ben Farmer on December 30, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP