Description
Implement namespaced and inheritable metadata at the class level.
Inspired on Meta classes from Django models and Django Rest Framework model serializers.
Quick Start
Installation
pip install classoptions
Simple inheritance
from classoptions import ClassOptionsMetaclass
from typing import Any
class Pizza(metaclass=ClassOptionsMetaclass):
_meta: Any
class DefaultMeta:
client_can_modify = True
notes = None
cooking_temp = 400
cooking_time = 1
class HawaiianPizza(Pizza):
ingredients = ["cheese", "ham", "pineapple"]
class Meta:
notes = "Do not judge the costumer."
private_note = "If planning a party, ask first if people like it."
print("Hawaiian Pizza:")
print("Ingredients:", ", ".join(HawaiianPizza.ingredients))
print("Cooking Temperature (F):", HawaiianPizza.cooking_temp)
print("Cooking Time (hours):", HawaiianPizza.cooking_time)
print("Client can modify:", HawaiianPizza._meta.client_can_modify)
print("Notes:")
print(HawaiianPizza._meta.notes)
print("Private Note:")
print(HawaiianPizza._meta.private_note)
Outputs:
Hawaiian Pizza:
Ingredients: cheese, ham, pineapple
Cooking Temperature (F): 400
Cooking Time (hours): 1
Client can modify: True
Notes:
Do not judge the costumer.
Private Note:
If planning a party, ask first if people like it.
Multiple Inheritance
Works similar to python inheritance, except we don't need to explicitly inherit from the parent class.
from classoptions import ClassOptionsMetaclass
from typing import Any
class A(metaclass=ClassOptionsMetaclass):
_meta: Any
class DefaultMeta:
color = "red"
size = 2
hello = "world"
i_like_pizza = True
class B(A):
class DefaultMeta:
color = "blue"
size = 3
class C(B):
class Meta:
size = 4 # Specific to C only
class D(A):
class DefaultMeta:
color = "black"
hello = "country"
class E(D, C):
class Meta:
i_like_hawaiian_pizza = "maybe"
print("E custom meta")
print("i_like_hawaiian_pizza:", E._meta.i_like_hawaiian_pizza)
print("\nInherited from B")
print("size:", E._meta.size)
print("\nInherited from D")
print("color:", E._meta.color)
print("hello:", E._meta.hello)
print("\nInherited from A")
print("i_like_pizza:", E._meta.i_like_pizza)
Outputs:
E custom meta
i_like_hawaiian_pizza: maybe
Inherited from B
size: 3
Inherited from D
color: black
hello: country
Inherited from A
i_like_pizza: True
Using other class/attribute names
With ClassOptionsMetaclass.factory
you can overwrite how you define default metadata, class specific metadata,
and how you access the result.
from classoptions import ClassOptionsMetaclass
from typing import Any
class A(metaclass=ClassOptionsMetaclass.factory("Options", "DefaultOptions", "_options")):
_options: Any
class DefaultOptions:
color = "red"
size = 2
cooking_temp = 400
cooking_time = 1
class B(A):
class Options:
color = "blue"
print("B color:", B._options.color)
print("B size:", B._options.size)
Outputs:
B color: blue
B size: 2
License
MIT License.