python-2.7:在类的setter方法中忽略doctests

时间:2014-04-28 12:25:16

标签: python python-2.7 properties setter doctest

为什么以下示例无法在 setter 方法中运行doctest?

class Foo:
    a = None

    @property
    def a(self):
        pass

    @a.setter
    def a(self, v):
        '''
        >>> 1 == 1
        False
        '''
        pass

if __name__ == "__main__":
    import doctest
    doctest.testmod()

调试器确认没有运行测试(上面的示例写入dtest.py):

>>> import dtest, doctest
>>> doctest.testmod(dtest)
TestResults(failed=0, attempted=0)

getter 方法中的相同测试正确执行,当然报告失败...

1 个答案:

答案 0 :(得分:5)

@a.setter装饰器会忽略文档字符串,而不会将其复制到生成的property对象中;在 getter 上设置文档字符串。

请参阅property documentation

  

如果给定,doc将是property属性的docstring。否则,属性将复制fget的docstring (如果存在)。

强调我的。

您的代码会产生:

>>> class Foo:
...     a = None
...     @property
...     def a(self):
...         pass
...     @a.setter
...     def a(self, v):
...         '''
...         >>> 1 == 1
...         False
...         '''
...         pass
...
>>> Foo.a
<property object at 0x101a21050>
>>> Foo.a.__doc__ is None
True

然后在 getter 上设置文档字符串,然后得到:

>>> class Foo:
...     a = None
...     @property
...     def a(self):
...         '''
...         >>> 1 == 1
...         False
...         '''
...         pass
...     @a.setter
...     def a(self, v):
...         pass
... 
>>> Foo.a
<property object at 0x101a210a8>
>>> Foo.a.__doc__
'\n        >>> 1 == 1\n        False\n        '

另一个丑陋的解决方法是重新创建属性,并明确地从setter中复制docstring:

class Foo:
    a = None

    @property
    def a(self):
        pass

    @a.setter
    def a(self, v):
        '''
        >>> 1 == 1
        False
        '''
        pass

    a = property(a.fget, a.fset, doc=a.fset.__doc__)