UGuntupalli
UGuntupalli

Reputation: 3

How to invoke default methods with attrs python package

All,

Thank you for taking the time to try and address my question. My question is related to a specific Python package called attrs (https://www.attrs.org/en/stable/). I am just getting started with it and tried asking the same question on the Github page and was asked to re-direct my question here.

I am looking for documentation that describes or examples that talk about how to invoke default method when defining classes using attrs. Here is an example of what I am looking to do:

Without using attrs

class Calculator: 
         def __init__(self, var_1: float, var_2: float): 
         """ Class initialization method
          
          :var_1: A positive integer 
          :var_2: Another positive integer 
          """ 
               self.var_1 = var_1 
               self.var_2 = var_2 
               self.sum = None

               # Invoke default method 
               self.set_sum() 
               
          def get_sum(): 
                self.var_1 + self.var_2 

           def set_sum(): 
                self.sum = self.get_sum()

Using attrs

from attrs import define, validators
from typing import Union


@define
class Calculator: 
          var_1: float = field(validator=[validators.instance_of(float), validators.ge(0.))
          var_2: float = field(validator=[validators.instance_of(float), validators.ge(0.))
          sum: Union[float, None] = field(default=None, init=False)

          def get_sum(): 
                self.var_1 + self.var_2 

           def set_sum(): 
                self.sum = self.get_sum()

If I know that for every instance of Calculator class, I want the sum to be set, I would typically want to invoke the method within my __init__ method definition. Can someone shed some light on how I can do that with attrs

Upvotes: 0

Views: 248

Answers (1)

gahjelle
gahjelle

Reputation: 76

I think you are looking for __attrs_post_init__() (https://www.attrs.org/en/stable/examples.html?highlight=post_init#other-goodies).

According to the documentation, it handles use cases when "you want to have your class’s __init__ method do more than just the initialization, validation, etc. that gets done for you automatically when using @define."

The docs show the following example:

@define
class C:
    x: int
    y: int
    z: int = field(init=False)

    def __attrs_post_init__(self):
        self.z = self.x + self.y

obj = C(x=1, y=2)

After running this code, obj will be initialized as C(x=1, y=2, z=3). Note that z=3 was set as the sum of x and y.

In practice, your .__attrs_post_init__() method will be called automatically at the end of the generated .__init__() method.

Upvotes: 1

Related Questions