__repr__
is used to return a string representation of an object, but in Python a function is also an object itself, and can have attributes.
How do I set the __repr__
of a function?
I see here that an attribute can be set for a function outside the function, but typically one sets a __repr__
within the object definition itself, so I'd like to set the repr within the function definition itself.
My use case is that I am using tenacity to retry a networking function with exponential backoff, and I want to log the (informative) name of the function I have called last.
retry_mysql_exception_types = (InterfaceError, OperationalError, TimeoutError, ConnectionResetError)
def return_last_retry_outcome(retry_state):
"""return the result of the last call attempt"""
return retry_state.outcome.result()
def my_before_sleep(retry_state):
print("Retrying {}: attempt {} ended with: {}\n".format(retry_state.fn, retry_state.attempt_number, retry_state.outcome))
@tenacity.retry(wait=tenacity.wait_random_exponential(multiplier=1, max=1200),
stop=tenacity.stop_after_attempt(30),
retry=tenacity.retry_if_exception_type(retry_mysql_exception_types),
retry_error_callback=return_last_retry_outcome,
before_sleep=my_before_sleep)
def connect_with_retries(my_database_config):
connection = mysql.connector.connect(**my_database_config)
return connection
Currently retry_state.fn
displays something like <function <lambda> at 0x1100f6ee0>
like @chepner says, but I'd like to add more information to it.
__repr__ (self) Returns a string as a representation of the object. Ideally, the representation should be information-rich and could be used to recreate an object with the same value.
The __repr__ method returns the string representation of an object. Typically, the __repr__() returns a string that can be executed and yield the same value as the object. In other words, if you pass the returned string of the object_name.
The repr method is used to get a string representation of a Python object. It is common to find people using it when creating models for their flask app. With the repr method, you can make a query from the database and print the result of the query.
The repr() function returns a printable representational string of the given object.
You could use a decorator that returns a class with the __call__
and __repr__
set:
class CustomReprFunc:
def __init__(self, f, custom_repr):
self.f = f
self.custom_repr = custom_repr
def __call__(self, *args, **kwargs):
return self.f(*args, **kwargs)
def __repr__(self):
return self.custom_repr(self.f)
def set_repr(custom_repr):
def set_repr_decorator(f):
return CustomReprFunc(f, custom_repr)
return set_repr_decorator
@set_repr(lambda f: f.__name__)
def func(a):
return a
print(repr(func))
I think a custom decorator could help:
import functools
class reprable:
"""Decorates a function with a repr method.
Example:
>>> @reprable
... def foo():
... '''Does something cool.'''
... return 4
...
>>> foo()
4
>>> foo.__name__
'foo'
>>> foo.__doc__
'Does something cool.'
>>> repr(foo)
'foo: Does something cool.'
>>> type(foo)
<class '__main__.reprable'>
"""
def __init__(self, wrapped):
self._wrapped = wrapped
functools.update_wrapper(self, wrapped)
def __call__(self, *args, **kwargs):
return self._wrapped(*args, **kwargs)
def __repr__(self):
return f'{self._wrapped.__name__}: {self._wrapped.__doc__}'
Demo: http://tpcg.io/uTbSDepz.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With