首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为函数本身设置repr?

如何为函数本身设置repr?
EN

Stack Overflow用户
提问于 2020-10-29 18:47:37
回答 5查看 718关注 0票数 5

__repr__用于返回对象的字符串表示,但在Python中,函数本身也是对象,可以有属性

如何设置函数的__repr__

我看到了这里,可以为函数外部的函数设置属性,但通常在对象定义本身中设置一个__repr__,所以我想在函数定义本身中设置repr。

我的用例是,我正在使用坚韧重试一个带有指数退避的网络函数,并且我想记录我上次调用的函数的(信息)名称。

代码语言:javascript
复制
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

目前,retry_state.fn显示类似于@chepner所说的<function <lambda> at 0x1100f6ee0>的内容,但是我想向它添加更多的信息。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2020-10-29 19:17:01

我认为一个定制的装潢师可以帮上忙:

代码语言:javascript
复制
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__}'

演示:http://tpcg.io/uTbSDepz

票数 4
EN

Stack Overflow用户

发布于 2020-10-29 19:04:45

您可以使用一个使用__call____repr__集返回类的装饰器:

代码语言:javascript
复制
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))
票数 6
EN

Stack Overflow用户

发布于 2020-10-29 18:51:41

已经准备好了。

代码语言:javascript
复制
>>> repr(lambda x:x)
'<function <lambda> at 0x1100f6ee0>'

问题是,function类型是不可变的,所以不能只为function.__repr__分配一个新函数,也不能创建function的子类型来覆盖__repr__。(即使可以定义子类实例,创建子类的实例也并不容易。)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64597425

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档