Enhancing Python with Field-based Enums

0

Rust’s enums are truly amazing, especially with their ability to hold fields, allowing you to fully embrace the beauty of functional programming. But what if Python could have such fantastic features too? Here’s where fieldenum comes into play!

Why do we need field-based Enums in Python?

Traditional Python `Enum` and `dataclass` each have their limitations. `Enum` cannot have fields, and `dataclass` lacks the concept of choices. However, `fieldenum` combines the strengths of both, allowing you to use enums with fields in Python.

Installation and Compatibility

Installing `fieldenum` is straightforward. Use the following command:

pip install fieldenum

This package is compatible with Python 3.10 and above. However, the submodule `fieldenum.enums` requires Python 3.12 or higher.

Usage

Basic Example

You can create a `fieldenum` by adding variables with `Variant` or `Unit` values to a class and decorating it with `@fieldenum`. Here’s an example:

from fieldenum import Variant, Unit, fieldenum

@fieldenum
class Message:
    Quit = Unit
    Write = Variant(str)

When using the defined `Message` enum, instantiate each variant as follows:

message = Message.Quit
write_message = Message.Write("Hello, World!")

Defining Variants

Every `fieldenum` can have variants, supporting both unit variants and tuple-based variants. Unit variants do not have fields, while tuple-based variants can have multiple fields.

Unit Variant
from fieldenum import Unit, fieldenum

@fieldenum
class Action:
    Stop = Unit
    Start = Unit

action = Action.Stop
if action is Action.Stop:
    print("Action is Stop")
Tuple-based Variant
from fieldenum import Variant, fieldenum

@fieldenum
class Command:
    Move = Variant(int, int)
    Speak = Variant(str)

command = Command.Move(10, 20)
print(command)

Named Variants

Named variants can be initialized using keyword arguments.

from fieldenum import Variant, fieldenum

@fieldenum
class Coordinate:
    Point2D = Variant(x=float, y=float)
    Point3D = Variant(x=float, y=float, z=float)

point = Coordinate.Point3D(x=1.0, y=2.0, z=3.0)
print(f"Point: {point.x}, {point.y}, {point.z}")

Various Use Cases

`fieldenum` helps you easily apply concepts like Railroad Oriented Programming or Option types in Python.

Using Option Type

Use the Option type to represent states that may or may not have a value.

from fieldenum.enums import Option, Some

optional_value = Option.new(input("Type anything!") or None)
match optional_value:
    case Some(value):
        print(f"Value: {value}")
    case Option.Nothing:
        print("No value")

In this example, the `Option.new()` method returns `Option.Some` if there is a value, or `Option.Nothing` if there isn’t.

Conclusion

`fieldenum` allows you to use field-based enums in Python, bringing the allure of functional programming to your Python projects. It helps you implement various data structures and patterns, combining Python’s flexibility with Rust’s power. Give it a try!

Reference: GitHub, “fieldenum”

Leave a Reply