MYCSS

2024-11-07

Python Enum, keys(), values(), items() with cached values using lru_cache.

Читаючи How to get all values from python enum class? знайшов цікаве для себе рішення для застосування class enum.Enum Python у парі з @functools.lru_cache


 

import sys
from enum import Enum
from functools import lru_cache
if sys.version_info >= (3, 11):
from enum import StrEnum
else:
class StrEnum(str, Enum): ...
class LruCachedEnum(Enum):
@classmethod
@lru_cache(maxsize=1)
def to_dict(cls):
print("##### singleton of to_dict")
return {e.name: e.value for e in cls}
@classmethod
@lru_cache(maxsize=1)
def items(cls):
print("##### singleton of items")
return [(e.name, e.value) for e in cls]
@classmethod
@lru_cache(maxsize=1)
def keys(cls):
print("##### singleton of keys")
return [e.name for e in cls]
@classmethod
@lru_cache(maxsize=1)
def values(cls):
print("##### singleton of values")
return [e.value for e in cls]
class MODES(StrEnum, LruCachedEnum):
ORIGINAL = "original"
REDUCED = "reduced"
NORMALIZED = "normalized"
CROPPED = "cropped"
CROPPED_REDUCED = "cropped_reduced"
class RIGHTS(StrEnum, LruCachedEnum):
PUBLIC = "public"
PRIVATE = "private"
class COLORS(LruCachedEnum):
RED = 0
GREEN = 1
BLUE = 2
if __name__ == "__main__":
print(type(MODES.ORIGINAL)) # Should be <enum 'MODES'>
print(MODES.ORIGINAL.value, MODES.ORIGINAL == "original")
print("\n# methods")
print(MODES.to_dict())
print(MODES.items())
print(MODES.keys())
print(MODES.values())
print("\n# next loop by use cache")
print(MODES.to_dict())
print(MODES.items())
print(MODES.keys())
print(MODES.values())
print("\n# is member:")
for v in ["original", "small", "cropped"]:
print(f"{v} is MEMBER of MODES: {v in MODES.values()}")
print("\n# methods of RIGHT")
print(RIGHTS.to_dict())
print(RIGHTS.to_dict())
print("\n# methods of COLORS")
print(COLORS.to_dict())
print(COLORS.RED.value)
print(COLORS.to_dict())
"""
<enum 'MODES'>
original True
# methods
##### singleton of to_dict
{'ORIGINAL': 'original', 'REDUCED': 'reduced', 'NORMALIZED': 'normalized', 'CROPPED': 'cropped', 'CROPPED_REDUCED': 'cropped_reduced'}
##### singleton of items
[('ORIGINAL', 'original'), ('REDUCED', 'reduced'), ('NORMALIZED', 'normalized'), ('CROPPED', 'cropped'), ('CROPPED_REDUCED', 'cropped_reduced')]
##### singleton of keys
['ORIGINAL', 'REDUCED', 'NORMALIZED', 'CROPPED', 'CROPPED_REDUCED']
##### singleton of values
['original', 'reduced', 'normalized', 'cropped', 'cropped_reduced']
# next loop by use cache
{'ORIGINAL': 'original', 'REDUCED': 'reduced', 'NORMALIZED': 'normalized', 'CROPPED': 'cropped', 'CROPPED_REDUCED': 'cropped_reduced'}
[('ORIGINAL', 'original'), ('REDUCED', 'reduced'), ('NORMALIZED', 'normalized'), ('CROPPED', 'cropped'), ('CROPPED_REDUCED', 'cropped_reduced')]
['ORIGINAL', 'REDUCED', 'NORMALIZED', 'CROPPED', 'CROPPED_REDUCED']
['original', 'reduced', 'normalized', 'cropped', 'cropped_reduced']
# is member:
original is MEMBER of MODES: True
small is MEMBER of MODES: False
cropped is MEMBER of MODES: True
# methods of RIGHT
##### singleton of to_dict
{'PUBLIC': 'public', 'PRIVATE': 'private'}
{'PUBLIC': 'public', 'PRIVATE': 'private'}
# methods of COLORS
##### singleton of to_dict
{'RED': 0, 'GREEN': 1, 'BLUE': 2}
0
{'RED': 0, 'GREEN': 1, 'BLUE': 2}
"""
Продовжуючи гратися, інші методи:
import sys
from enum import Enum
from functools import lru_cache
if sys.version_info >= (3, 11):
from enum import StrEnum
else:
class StrEnum(str, Enum): ...
class LruCachedEnum(Enum):
@classmethod
@lru_cache(maxsize=1)
def to_dict(cls):
print("##### singleton of to_dict")
return {e.name: e.value for e in cls}
@classmethod
@lru_cache(maxsize=1)
def items(cls):
print("##### singleton of items")
return [(e.name, e.value) for e in cls]
@classmethod
@lru_cache(maxsize=1)
def keys(cls):
print("##### singleton of keys")
return [e.name for e in cls]
@classmethod
@lru_cache(maxsize=1)
def values(cls):
print("##### singleton of values")
return [e.value for e in cls]
class MODES(StrEnum, LruCachedEnum):
ORIGINAL = "original"
REDUCED = "reduced"
NORMALIZED = "normalized"
CROPPED = "cropped"
CROPPED_REDUCED = "cropped_reduced"
class RIGHTS(StrEnum, LruCachedEnum):
PUBLIC = "public"
PRIVATE = "private"
class COLORS(LruCachedEnum):
RED = 0
GREEN = 1
BLUE = 2
def cached_method(func):
# Dictionary to store cache for each class-method combination
cache = {}
def wrapper(cls):
# Cache key based on class and function name
cache_key = (cls, func.__name__)
if cache_key in cache:
return cache[cache_key]
# Calculate and cache the result
result = func(cls)
cache[cache_key] = result
print(f"##### Caching result for {cls.__name__}.{func.__name__}")
return result
return wrapper
class CachedDecoratorEnum(Enum):
@classmethod
@cached_method
def to_dict(cls):
return {e.name: e.value for e in cls}
@classmethod
@cached_method
def items(cls):
print("##### singleton of items")
return [(e.name, e.value) for e in cls]
@classmethod
@cached_method
def keys(cls):
print("##### singleton of keys")
return [e.name for e in cls]
@classmethod
@cached_method
def values(cls):
print("##### singleton of values")
return [e.value for e in cls]
class RIGHTS_CD(StrEnum, CachedDecoratorEnum):
PUBLIC = "public"
PRIVATE = "private"
class COLORS_CD(CachedDecoratorEnum):
RED = 0
GREEN = 1
BLUE = 2
class Cache:
_cache = {}
@classmethod
def get_cached_result(cls, key, calculate):
# If the result is cached, return it
if key in cls._cache:
return cls._cache[key]
# Otherwise, calculate, cache, and return the result
result = calculate()
cls._cache[key] = result
print(f"##### Caching result for {key}")
return result
class CachedEnum(Enum):
@classmethod
def to_dict(cls):
key = (cls, "to_list")
return Cache.get_cached_result(key, lambda: [e.value for e in cls])
@classmethod
def to_list(cls):
key = (cls, "to_list")
return Cache.get_cached_result(key, lambda: [e.value for e in cls])
class RIGHTS_C(StrEnum, CachedEnum):
PUBLIC = "public"
PRIVATE = "private"
class COLORS_C(CachedEnum):
RED = 0
GREEN = 1
BLUE = 2
class CachedMROEnum(Cache, Enum):
@classmethod
def to_dict(cls):
# This will now call Cache.get_cached_result because Cache is first in the MRO
return super().get_cached_result(
(cls, "to_dict"), lambda: {e.name: e.value for e in cls}
)
@classmethod
def to_list(cls):
return super().get_cached_result(
(cls, "to_list"), lambda: [e.value for e in cls]
)
class RIGHTS_CMRO(StrEnum, CachedEnum):
PUBLIC = "public"
PRIVATE = "private"
class COLORS_CMRO(CachedMROEnum):
RED = 0
GREEN = 1
BLUE = 2
class CacheStateEnum(Enum):
@classmethod
def to_dict(cls, state={}):
if state.get(cls):
return state[cls]["result"]
result = {e.name: e.value for e in cls}
state[cls] = {"result": result}
print("##### singleton of to_dict")
return result
@classmethod
def to_list(cls, state={}):
if state.get(cls):
return state[cls]["result"]
result = [e.value for e in cls]
state[cls] = {"result": result}
print("##### singleton of to_list")
return result
class RIGHTS_CS(StrEnum, CacheStateEnum):
PUBLIC = "public"
PRIVATE = "private"
class COLORS_CS(CacheStateEnum):
RED = 0
GREEN = 1
BLUE = 2
if __name__ == "__main__":
print(type(MODES.ORIGINAL)) # Should be <enum 'MODES'>
print(MODES.ORIGINAL.value, MODES.ORIGINAL == "original")
print("\n# methods")
print(MODES.to_dict())
print(MODES.items())
print(MODES.keys())
print(MODES.values())
print("\n# next loop by use cache")
print(MODES.to_dict())
print(MODES.items())
print(MODES.keys())
print(MODES.values())
print("\n# is member:")
for v in ["original", "small", "cropped"]:
print(f"{v} is MEMBER of MODES: {v in MODES.values()}")
print("\n# methods of RIGHT")
print(RIGHTS.to_dict())
print(RIGHTS.to_dict())
print("\n# methods of COLORS")
print(COLORS.to_dict())
print(COLORS.RED.value)
print(COLORS.to_dict())
print("\n# methods 1 decorator")
print(RIGHTS_CD.to_dict())
print(COLORS_CD.to_dict())
print("\n# methods 2 decorator")
print(RIGHTS_CD.to_dict())
print(COLORS_CD.to_dict())
print("\n# methods 1")
print(RIGHTS_C.to_dict())
print(COLORS_C.to_dict())
print("\n# methods 2")
print(RIGHTS_C.to_dict())
print(COLORS_C.to_dict())
print("\n# methods 1 nested ")
print(RIGHTS_CMRO.to_dict())
print(COLORS_CMRO.to_dict())
print("\n# methods 2 nested")
print(RIGHTS_CMRO.to_dict())
print(COLORS_CMRO.to_dict())
print("\n# methods 1 state ")
print(RIGHTS_CS.to_dict())
print(RIGHTS_CS.to_list())
print(COLORS_CS.to_dict())
print(COLORS_CS.to_list())
print("\n# methods 2 state")
print(RIGHTS_CS.to_dict())
print(RIGHTS_CS.to_list())
print(COLORS_CS.to_dict())
print(COLORS_CS.to_list())
"""
<enum 'MODES'>
original True
# methods
##### singleton of to_dict
{'ORIGINAL': 'original', 'REDUCED': 'reduced', 'NORMALIZED': 'normalized', 'CROPPED': 'cropped', 'CROPPED_REDUCED': 'cropped_reduced'}
##### singleton of items
[('ORIGINAL', 'original'), ('REDUCED', 'reduced'), ('NORMALIZED', 'normalized'), ('CROPPED', 'cropped'), ('CROPPED_REDUCED', 'cropped_reduced')]
##### singleton of keys
['ORIGINAL', 'REDUCED', 'NORMALIZED', 'CROPPED', 'CROPPED_REDUCED']
##### singleton of values
['original', 'reduced', 'normalized', 'cropped', 'cropped_reduced']
# next loop by use cache
{'ORIGINAL': 'original', 'REDUCED': 'reduced', 'NORMALIZED': 'normalized', 'CROPPED': 'cropped', 'CROPPED_REDUCED': 'cropped_reduced'}
[('ORIGINAL', 'original'), ('REDUCED', 'reduced'), ('NORMALIZED', 'normalized'), ('CROPPED', 'cropped'), ('CROPPED_REDUCED', 'cropped_reduced')]
['ORIGINAL', 'REDUCED', 'NORMALIZED', 'CROPPED', 'CROPPED_REDUCED']
['original', 'reduced', 'normalized', 'cropped', 'cropped_reduced']
# is member:
original is MEMBER of MODES: True
small is MEMBER of MODES: False
cropped is MEMBER of MODES: True
# methods of RIGHT
##### singleton of to_dict
{'PUBLIC': 'public', 'PRIVATE': 'private'}
{'PUBLIC': 'public', 'PRIVATE': 'private'}
# methods of COLORS
##### singleton of to_dict
{'RED': 0, 'GREEN': 1, 'BLUE': 2}
0
{'RED': 0, 'GREEN': 1, 'BLUE': 2}
# methods 1 decorator
##### Caching result for RIGHTS_CD.to_dict
{'PUBLIC': 'public', 'PRIVATE': 'private'}
##### Caching result for COLORS_CD.to_dict
{'RED': 0, 'GREEN': 1, 'BLUE': 2}
# methods 2 decorator
{'PUBLIC': 'public', 'PRIVATE': 'private'}
{'RED': 0, 'GREEN': 1, 'BLUE': 2}
# methods 1
##### Caching result for (<enum 'RIGHTS_C'>, 'to_list')
['public', 'private']
##### Caching result for (<enum 'COLORS_C'>, 'to_list')
[0, 1, 2]
# methods 2
['public', 'private']
[0, 1, 2]
# methods 1 nested
##### Caching result for (<enum 'RIGHTS_CMRO'>, 'to_list')
['public', 'private']
##### Caching result for (<enum 'COLORS_CMRO'>, 'to_dict')
{'RED': 0, 'GREEN': 1, 'BLUE': 2}
# methods 2 nested
['public', 'private']
{'RED': 0, 'GREEN': 1, 'BLUE': 2}
# methods 1 state
##### singleton of to_dict
{'PUBLIC': 'public', 'PRIVATE': 'private'}
##### singleton of to_list
['public', 'private']
##### singleton of to_dict
{'RED': 0, 'GREEN': 1, 'BLUE': 2}
##### singleton of to_list
[0, 1, 2]
# methods 2 state
{'PUBLIC': 'public', 'PRIVATE': 'private'}
['public', 'private']
{'RED': 0, 'GREEN': 1, 'BLUE': 2}
[0, 1, 2]
"""


Немає коментарів:

Коли забув ти рідну мову, біднієш духом ти щодня...
When you forgot your native language you would become a poor at spirit every day ...

Д.Білоус / D.Bilous
Рабів до раю не пускають. Будь вільним!

ipv6 ready