Skip to content

Instantly share code, notes, and snippets.

@TheArcherST
Created July 10, 2022 18:17
Show Gist options
  • Save TheArcherST/a3b73ad26c6eeb96e8f07c5a10f1ce36 to your computer and use it in GitHub Desktop.
Save TheArcherST/a3b73ad26c6eeb96e8f07c5a10f1ce36 to your computer and use it in GitHub Desktop.
class Repr:
"""Repr method generator
Automatically parse object init-based definition.
To include extra fields, list them in `__repr_include__`.
>>> class User(Repr):
... __repr_include__ = ['uri']
...
... def __init__(self, uid: int, uname: str, referral: int = None):
... self.id = uid
... self.uname = uname
... self.referral = referral
...
... @property
... def uri(self):
... return f'https://example.com/users/{self.id}'
>>> User(2, uname='Bob', referral=1)
User(2, uname='Bob', referral=1) # uri='https://example.com/users/2'
"""
__repr_include__ = []
def __new__(cls, *args, **kwargs):
_ = super().__new__(cls)
_._source_data_ = (args, kwargs)
return _
def __repr__(self):
"""Auto generated repr.
Return code of object init-definition, based on name
and data, provided while initialization.
Extra fields from `__repr_include__` will be joined
as comment for initialization code. If field not found,
this key will be just skipped.
"""
arguments = ', '.join(map(repr, self._source_data_[0]))
keyword_arguments = ', '.join(f'{k}={repr(v)}' for k, v in self._source_data_[1].items())
include = ', '.join(f'{k}={repr(getattr(self, k))}'
for k in self.__repr_include__
if k in self.__dir__())
if keyword_arguments:
keyword_arguments = ', ' + keyword_arguments
result = f'{self.__class__.__name__}({arguments + keyword_arguments})'
if include:
result += ' # ' + include
return result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment