Created
September 18, 2019 22:11
-
-
Save xmodar/362dc860642b8ff9c765c72c740e213b to your computer and use it in GitHub Desktop.
Create namedtuple types for function outputs only once with nice type name.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import namedtuple | |
from types import MethodType, FunctionType | |
# using neither typing.NamedTuple nor dataclasses.dataclass | |
def named_tuple(function, field_names, *args, name=None, **kwargs): | |
"""Memoize namedtuple types for function outputs.""" | |
if isinstance(function, MethodType): | |
function = function.__func__ | |
assert isinstance(function, FunctionType) | |
if name is None or name.startswith('.'): | |
suffix = '' if name is None else name | |
name = function.__qualname__ + suffix | |
name = name.replace('.', chr(0xB7)) # centered dot | |
assert name.isidentifier(), f'Invalid identifier: {name}' | |
if not hasattr(function, name): | |
output_type = namedtuple(name, field_names, *args, **kwargs) | |
output_type.__module__ = function.__module__ | |
setattr(function, name, output_type) | |
return getattr(function, name) | |
# usage examples... | |
def f(): | |
Output = named_tuple(f, ('x', 'y')) | |
return Output(3, 2) | |
def g(): | |
# always use unique names for the same function | |
Point = named_tuple(g, ('x', 'y'), name='Point') | |
# prepend a dot to the name for a fully qualified type name | |
Line = named_tuple(g, ('start', 'end'), name='.Line') | |
return Line(Point(2, 1), Point(3, 2)) | |
class A: | |
def f(self): | |
Output = named_tuple(self.f, ('x', 'y')) | |
return Output(3, 2) | |
@classmethod | |
def g(cls): | |
Output = named_tuple(cls.g, ('x', 'y')) | |
return Output(3, 2) | |
@staticmethod | |
def h(): | |
Output = named_tuple(A.h, ('x', 'y')) | |
return Output(3, 2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment