Придумав цікаву штуку для простішого і, можливо, більш інтуїтивного для початківців виклику функції, що приймає enum як параметр.
Ось приклад коду:
from graphics_2d_library import draw_pixel
draw_pixel(
x=10,
y=10,
color=draw_pixel.color.BLUE # кольори відразу під рукою
)
Реалізація graphics_2d_library
:
from enum import Enum
class Color(Enum):
RED = "red"
GREEN = "green"
BLUE = "blue"
def draw_pixel(x, y, color=Color.RED):
print(f"Drawing pixel at (x={x}, y={y}) with color: {color}")
draw_pixel.color = Color # пов'язуємо draw_pixel і Color enum
Зверніть увагу на останній рядок коду: оскільки функція у мові Python теж є об’єктом - то можна додавати які завгодно атрибути до неї.
Автодоповнення теж працює:
Власний enum
Як першовідкривач даю назву цьому трюку - “Власний enum” (Owned enum), але відкритий для Ваших пропозицій).
Такий підхід - всього лиш домовленість, яка проте дозволяє зменшити кількість імпортованих сутностей і покращити колокацію коду. Ось ще один приклад:
from graphics_2d_library import draw_pixel, draw_line
draw_pixel(
x=10,
y=10,
color=draw_pixel.color.BLUE
)
draw_line(
start_x=0,
start_y=0,
end_x=10,
end_y=10,
color=draw_line.color.BLUE,
style=draw_line.style.DASHED,
)
Альтернатива?
Звичайно, можна було б скористатись підказками типів, але, все-одно, було б потрібно імпортувати enum Color
.
from graphics_2d_library import draw_pixel, Color
draw_pixel(
x=10,
y=10,
color=Color.BLUE
)
Альтернативна реалізація модулю graphics_2d_library
(без власний enum’у)
from enum import Enum
class Color(Enum):
RED = "red"
GREEN = "green"
BLUE = "blue"
def draw_pixel(x, y, color: Color = Color.BLUE):
print(f"Drawing pixel at ({x}, {y}) with color: {color}")
Натхнення і Prior work
Синтаксично надихався просторами імен JSX, які були додані у React версії 0.11.0 аж у 2014 (!) році. Думаю, вперше їх побачив у документації Semantic UI React, вони використовують цей підхід з 2015 року.
Гарний приклад містить також документація Radix UI:
const PopoverDemo = () => (
<Popover.Root>
<Popover.Trigger>More info</Popover.Trigger>
<Popover.Portal>
<Popover.Content>
Some more info…
<Popover.Arrow />
</Popover.Content>
</Popover.Portal>
</Popover.Root>
);