【问题标题】:Why this decorator can't get imported from module with "from module import *"?为什么这个装饰器不能用“from module import *”从模块中导入?
【发布时间】:2012-08-20 14:25:41
【问题描述】:

我在一个模块中有以下装饰器:

class CachedProperty(object):
    """Decorator that lazy-loads the value of a property.

    The first time the property is accessed, the original property function is
    executed. The value it returns is set as the new value of that instance's
    property, replacing the original method.
    """

    def __init__(self, wrapped):
        self.wrapped = wrapped
        try:
            self.__doc__ = wrapped.__doc__
        except:
            pass

    def __get__(self, instance, instance_type=None):
        if instance is None:
            return self

        value = self.wrapped(instance)
        setattr(instance, self.wrapped.__name__, value)

        return value

我想像这样从模块中导入这个装饰器和其他东西:

from clang.cindex import *

但我无法以这种方式导入单个装饰器,如果我这样做,它就可以工作:

from clang.cindex import CachedProperty

那么我可以使用@CachedProperty

为什么我不能通过* 导入这个类,而我可以导入其他类?

【问题讨论】:

  • import * 往往会引起人们的不满,因为它会造成名称冲突,我很好奇你会遇到什么错误?
  • 在使用 @CachedProperty 装饰某些属性时,我收到一条错误消息,提示未定义 CachedProperty。
  • 我知道它不受欢迎,但我仍然想知道它为什么不起作用。没有发生名称冲突。
  • 不想侮辱你的智力,但你确定CachedProperty 是在你导入的模块中定义的吗? clange.cindex 是子包吗?如果是这样,您必须在模块中设置 __all__ 变量以告诉 python 在您执行 from _ import * 时要导入哪些名称

标签: python properties import decorator


【解决方案1】:

查看在模块顶部附近是否定义了名为__all__ 的变量。如果是这样,它将分配给它的字符串名称序列(列表或元组)。这些是由from ... import * 语句导入的模块的公共名称。

如果未定义 __all__ 名称,则模块中定义的所有名称(以及从其他模块导入的名称)不以下划线开头,都将被视为公共名称。

确保__all__ 序列包含字符串“CachedProperty”。

【讨论】:

  • 谢谢,我是 Python 新手,__all__ 位于 3000 行模块的底部...
  • 很高兴我能帮上忙。我以前从未见过在模块底部附近定义过__all__。将它放在有助于记录模块公共名称的顶部附近更有意义。事实上,我倾向于每行放一个名字,每行后面都有一个简短的评论描述。
  • 看来我只是运气不好才熟悉 python 的__all__ =)。看看底部,没有任何文档:llvm.org/viewvc/llvm-project/cfe/trunk/bindings/python/clang/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-03
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
  • 1970-01-01
相关资源
最近更新 更多