da ich mich über die Feiertage irgendwie beschäftigen muss, habe ich heute ein wenig Unsinn mit Python getrieben.
Herausgekommen ist dabei u.a. Coroutine-basierter Properties, welche Getter und Setter in einer Methode vereinheitlichen.
Der Code unten ist auch als Gist verfügbar.
Code: Alles auswählen
#! /usr/bin/env python3
# lsimports.py - List imported modules of Python projects.
#
# Copyright (C) 2020 Richard Neumann <mail at richard dash neumann period de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""Coroutine-based two-in-one decorator."""
from contextlib import suppress
from functools import wraps
from math import pi, sqrt
from typing import Callable
def coroproperty(method: Callable) -> property:
"""Single decorator for getter and setter methods."""
@wraps(method)
def getter(self):
"""Property setter function."""
coro = method(self)
value = next(coro)
coro.close()
return value
@wraps(method)
def setter(self, value):
"""Property getter function."""
coro = method(self)
next(coro)
next(coro)
with suppress(StopIteration):
coro.send(value)
return property(getter, setter)
class Circle:
"""Information about a circle."""
def __init__(self, radius: float):
"""Initializes the circle with its radius."""
self.radius = radius
@coroproperty
def diameter(self):
"""Gets and sets the diameter."""
yield self.radius * 2
self.radius = (yield) / 2
@coroproperty
def circumference(self):
"""Gets and sets the circumference."""
yield self.diameter * pi
self.diameter = (yield) / pi
@coroproperty
def area(self):
"""Gets and sets the area."""
yield pow(self.radius, 2) * pi
self.radius = sqrt((yield) / pi)
if __name__ == '__main__':
circle = Circle(42)