Skip to content

zincware/ZnInit

Repository files navigation

Coverage Status PyTest PyPI version code-style Binder zincware

ZnInit - Automatic Generation of __init__ based on Descriptors

This package provides a base class for dataclass like structures with the addition of using Descriptors. The main functionality is the automatic generation of an keyword-only__init__ based on selected descriptors. The descriptors can e.g. overwrite __set__ or __get__ or have custom metadata associated with them. The ZnInit package is used by ZnTrack to enable lazy loading data from files as well as distinguishing between different types of descriptors such as zn.params or zn.outputs. An example can be found in the examples directory.

Example

The most simple use case is a replication of a dataclass like structure.

from zninit import ZnInit, Descriptor


class Human(ZnInit):
    name: str = Descriptor()
    language: str = Descriptor("EN")


# This will generate the following init:
def __init__(self, *, name, language="EN"):
    self.name = name
    self.language = language


fabian = Human(name="Fabian")
# or
fabian = Human(name="Fabian", language="DE")

The benefit of using ZnInit comes with using descriptors. You can subclass the zninit.Descriptor class and only add certain kwargs to the __init__ defined in init_descriptors: list. Furthermore, a post_init method is available to run code immediately after initializing the class.

from zninit import ZnInit, Descriptor


class Input(Descriptor):
    """A Parameter"""


class Metric(Descriptor):
    """An Output"""


class Human(ZnInit):
    _init_descriptors_ = [Input] # only add Input descriptors to the __init__
    name: str = Input()
    language: str = Input("DE")
    date: str = Metric()  # will not appear in the __init__

    def _post_init_(self):
        self.date = "2022-09-16"


julian = Human(name="Julian")
print(julian) # Human(language='DE', name='Julian')
print(julian.date)  # 2022-09-16
print(Input.get_dict(julian)) # {"name": "Julian", "language": "DE"}

One benefit of ZnInit is that it also allows for inheritance.

from zninit import ZnInit, Descriptor

class Animal(ZnInit):
    age: int = Descriptor()

class Cat(Animal):
    name: str = Descriptor()

billy = Cat(age=4, name="Billy")