from typing import Protocol, Self from dataclasses import dataclass class Trait(Protocol): @classmethod def new() -> Self: ... def make_noise(self) -> str: ... @dataclass class Dog: name: str noise: str = "wuff" @classmethod def new(cls, value: float): return cls(value) def make_noise(self): self.bark() def bark(self): print(self.noise) @dataclass class Bird: noise: str = "piep" @classmethod def new(cls, value: float): return cls(value) def make_noise(self): self.tweet() def tweet(self): print(self.noise) def main(): print("Hi") animals: list[Trait] = [ Dog("Schnuffi"), Bird(), Dog("Bello", "bell"), Bird("zirp"), ] for i in animals: i.make_noise() if __name__ == "__main__": main()