No project description provided
Project description
Table of Contents
- Table of Contents
Introduction
dataclass alternative with a greater emphasis on the 'class' aspect.
Extract features baozi offers
- Inheritance
- Immutability
- Keyword-only arguments and random order attributes
- Support user-defined
__pre_init__
method that gets executed before class instantiation - Typecasting(experimental)
Installation
pip install baozi
Usage
1. Usage of plain Struct
from baozi import Struct
class Person(Struct, kw_only=True):
age: int = 15
name: str
p = Person(name="baozi")
pre_init hook
class B(baozi.Struct):
name: str
age: int
@classmethod
def __pre_init__(cls, **data):
data["age"] = int(data["age"])
return data
assert asdict(B(name="name", age="15")) == {"name": "name", "age": 15}
-
Note here that attribute with default value does not have to show before regular attributeo
-
You might place dataclass configration directly in class inheritance
-
configs will be passed to subclasses
-
config class meta by passing class arguments or defining
__model_config__
field in the class
2. Usage of FrozenStruct
baozi is fully compatible with dataclasses.dataclass
from dataclass import is_dataclass
from baozi import FrozenStruct
assert is_dataclass(FrozenStruct)
FrozenStruct is equal to dataclass(frozen=True, slots=True, kw_only=True)
from baozi import FrozenStruct, field
from datetime import datetime
class Event(FrozenStruct):
name: str
create_at: datetime = field(default_factory=datetime.now)
>> e = Event(name="event")
>> assert isinstance(e.created_at, datetime)
>> e.created_at = datetime.now()
dataclasses.FrozenInstanceError: cannot assign to field 'created_at'
Defining FrozenStruct with mutable fields would raise error
since any mutable field would cause failure in immutability of the class
from baozi import FrozenStruct
class Mutable(FrozenStruct):
address: list[str]
baozi.MutableFieldError
Technical Details
config override order
baozi receive config in following order:
- config defined explicitly using
__model_config__
field defined in the class - config defined in the inheritance params
- config defined in the parent class of current class
- default config of baozi, which goes like this:
init=True
repr=True
eq=True
order=False
unsafe_hash=False
frozen=False
match_args=True
kw_only=True
slots=False
Struct default: kw_only=True
FrozenStruct defaults: kw_only=True frozen=True slots=True
Rationale of existence
why wouldn't I just use dataclass?
Mostly because of the decorator approach, dataclass uses decorators for transforming a regular class into a dataclass, and when I use dataclass in production, I soon realize that:
-
Code repetition, when there are tons of dataclasses, you are going to decorate them with
@dataclass
over and over again -
Error-prone, for non-trivial application, you often have different configuration of dataclass, like
@dataclass(frozen)
, if you inherit from a frozen dataclass and you use regular@dataclass
decorator, odds are you are going to have a bad time. -
It simply does not make sense to use decorator, when you decorating a class, it implies that your class would work just fine without the decorator, and that is not the case, if you get rid of the
@dataclass
decorator, your class won't work.
why wouldn't I just use pydantic.BaseModel?
Mostly because of You don't need validation, and you can use both.
pydantic is very powerful and strong and I use it in various projects, but there are certain scenarios where I find pydantic to be an overkill.
-
Data are already validated in the API layer, and once the input goes through API and penetrate into my application layer, i know those data are safe, cause they are generated by my code.
-
performance, despite how performant pydantic is, depending on complexity, it is ususally 5x to 100x times slower than a dataclass, which is essentially a regular python class. baozi is constantly faster than pydantic, especially for model with complex validation logic(since baozi does not validate by default), baozi also support usage of slots, which effciently cut about 1/3 of memory usage comparing to regular python class.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file baozi-0.0.6.tar.gz
.
File metadata
- Download URL: baozi-0.0.6.tar.gz
- Upload date:
- Size: 9.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 69ce249763684af8c2360ae2cee6cacfd38594ee00b025ec9b9eaf2ac8cedc8e |
|
MD5 | e69e817ce3f17994673e717d67d9033f |
|
BLAKE2b-256 | e11282205a901f778120fe9e69c2f5834c7e8e94fda8a7a88c0bd7b0a06a7ad7 |
File details
Details for the file baozi-0.0.6-py3-none-any.whl
.
File metadata
- Download URL: baozi-0.0.6-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 33c97422d1f3a1d3993a1c10122700e1d3225bd7d82d97bbb24b6e23018167a6 |
|
MD5 | 87f5810182351361f3f1366d173de15c |
|
BLAKE2b-256 | e0501dc5b0ba297021f0bc639d60db95e6bc938706d5b8992cf433e6c25bf01c |