2012-08-25 42 views
3

我有一个模块内的以下装饰:为什么这个装饰器无法从“从模块导入*”模块导入?

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

为什么我不能通过*导入此类,而我能够导入其他类?

+0

'import *'往往会因为可以创建名称冲突而皱眉,我很好奇你会得到什么错误? –

+0

用@CachedProperty装饰一些属性时,我得到一个错误,说CachedProperty没有定义。 –

+0

我知道这是不好的,但我仍然想知道为什么它不起作用。没有名称冲突发生。 –

回答

4

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

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

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

+1

谢谢,我是Python的新手,'__all__'在底部3000线模块... –

+0

很高兴我能帮到你。我从未在模块底部附近定义过__all__。更有意义的是把它放在靠近顶部,它有助于记录模块公用名。实际上,我倾向于在每行后面加上一个简短的评论说明。 –

+0

看来我只是运气不佳而已经熟悉python的'__all__' =)。只需看看下面的内容,不需要任何文档:https://llvm.org/viewvc/llvm-project/cfe/trunk/bindings/python/clang/cindex.py?logsort=cvs&view=markup&sortby=author –