Home > other >  How to properly set multiple dependent attributes in a class?
How to properly set multiple dependent attributes in a class?

Time:09-17

I am looking for a way to set multiple dependent attributes in a class. Maybe this example further illustrates what I am trying to do. Currently I am solving this issue with multiple nested try statements. This does not seem the right way.

r"""
Example on sine-wave, where: a * sin(2 * pi * f * t   phi) = a * sin(omega * t   phi)
"""
import numpy as np


class SineWave:
    def __init__(self, a: float = 1., phi: float = 0., f: float = None, omega: float = None):
        self.a = a
        self.f = f
        self.phi = phi
        self.omega = omega

        self.post_init()

    def post_init(self) -> None:
        try:
            self.f = self.omega / (2 * np.pi)
        except TypeError:
            self.omega = 2 * np.pi * self.f
            
    def __call__(self, t: float) -> float:
        return self.a * np.sin(self.omega * t   self.phi)


if __name__ == '__main__':
    sin = SineWave(f=1)
    print(sin(np.pi))

What is the correct way of doing this?

CodePudding user response:

Given your logic, it must then be required that at least one of the arguments f and omega must be set, otherwise there should be a failure. You can assert this with the following statement:

def __init__(self, a: float = 1., phi: float = 0., f: float = None, omega: float = None):
    if all(arg is None for arg in [f, omega]):  # This is handy if you have multiple variables. But this could also be simply <if f is None and omega is None:>
        raise ValueError("Required arguments are null")
    ...

After that check, the design for the next parts of the code is straightforward as we know that at least one of them was set:

def __init__(...):
    ...
    self.f = f if f is not None else omega / (2 * np.pi)
    self.omega = omega if omega is not None else 2 * np.pi * f
    ...
  • Related