如何使用@property decorator作为模块属性?

2024-10-04 01:28:20 发布

您现在位置:Python中文网/ 问答频道 /正文

遵循PEP-562:

https://www.python.org/dev/peps/pep-0562/

现在可以为模块定义属性。不幸的是,一些内置组件还没有适应这个新特性。在以下代码中:

@property
def lazyFn():
    return 3

v = lazyFn

v

理想情况下v应该具有属性值3。不幸的是,@property的当前实现只产生以下结果:

<property at 0x7f3e703eae30>

我该如何修复它,使其按预期运行?或者,在哪里可以找到具有适当实现的替换?你知道吗


Tags: 模块httpsorgdev属性定义www组件
1条回答
网友
1楼 · 发布于 2024-10-04 01:28:20

我不敢相信答案会有多简单(而且这不是一个内置或插销),不需要反射、模块、setattr或PEP-562。我只需要定义一个装饰者:


def lazy(fn):
    if fn.__name__ == fn.__qualname__:
        # not a property
        result = fn()
        return result
    else:
        return LazyProperty(fn)

# the following are from PyPI lazy library
class LazyProperty(object):
    """lazy descriptor
    Used as a decorator to create lazy attributes. Lazy attributes
    are evaluated on first use.
    """

    def __init__(self, func):
        self.__func = func
        functools.wraps(self.__func)(self)

    def __get__(self, inst, inst_cls):
        if inst is None:
            return self

        if not hasattr(inst, '__dict__'):
            raise AttributeError("'%s' object has no attribute '__dict__'" % (inst_cls.__name__,))

        name = self.__name__
        if name.startswith('__') and not name.endswith('__'):
            name = '_%s%s' % (inst_cls.__name__, name)

        value = self.__func(inst)
        inst.__dict__[name] = value
        return value

要测试它:

nn = 0


@lazy
def fn1():
    global nn
    nn = nn + 1
    return nn


@dataclass
class HasFn2(object):
    nn = 0

    @lazy
    def fn2(self):
        self.nn = self.nn + 1
        return self.nn


def test_lazy():

    vs1 = [fn1 for i in range(0, 5)]
    assert vs1 == [1, 1, 1, 1, 1]

    c = HasFn2()
    vs2 = [c.fn2 for i in range(0, 5)]
    assert (vs2 == [1, 1, 1, 1, 1])

请纠正我,如果这个执行是有缺陷的

相关问题 更多 >