首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于描述符的Python docstring

用于描述符的Python docstring
EN

Stack Overflow用户
提问于 2016-05-16 13:28:56
回答 1查看 777关注 0票数 13

我使用描述符来定义接口类的寄存器:

代码语言:javascript
复制
class Register(object):
    def __init__(self, address, docstring="instance docstring"):
        self.address = address    
        self.__doc__ = docstring

    def __get__(self, obj, objtype):
        return obj.read(self.address)

    def __set__(self, obj, val):
        return obj.write(self.address, val)

class Interface(object):
    r = Register(0x00, docstring="the first register") 

我希望ipython的用户能够执行以下操作之一:

代码语言:javascript
复制
i = Interface()
i.r? #should show the docstring "the first register"

代码语言:javascript
复制
i = Interface()
i.r(  #should show the docstring "the first register" when parentheses are opened

但是,docstring总是来自obj.read返回的int对象,而不是指定的docstring。在这种情况下,有方法显示正确的docstring吗?

如果我不是使用描述符,而是手动定义它们,则当括号打开时,它可以工作:

代码语言:javascript
复制
class Interface(object):
    @property
    def r(self):
        """this docstring will be shown alternatively"""
        return self.read(0x0)

    @r.setter
    def r(self,v):
        """this is the docstring that is shown"""
        self.write(0x0,v)

i = Interface()
i.r( #the right docstring pops up here once i open the bracket

如果setter没有定义docstring,则在打开括号时显示一个getter。

我是否可以通过在没有不合理开销的情况下使用描述符来获得相同的行为呢?

我的问题有点类似于这个问题,但没有给出令人满意的答案:在Python描述符中创建动态文档字符串

EN

回答 1

Stack Overflow用户

发布于 2022-03-29 18:50:22

有两个问题。首先,描述符API也适用于类。因此,当Ipython试图从类中获取描述符时,实例__get__逻辑将被调用,这恰好会导致AttributeError失败,因此描述符将被忽略。在您的示例中,如果试图从Interface获取属性,则会引发一个错误,因为它试图在实例上运行(在本例中为None ):

代码语言:javascript
复制
In [25]: Interface.r
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-25-dd7a6e721f7e> in <module>
----> 1 Interface.r

<ipython-input-24-7d19c1ba4fe6> in __get__(self, obj, objtype)
      5 
      6     def __get__(self, obj, objtype):
----> 7         return obj.read(self.address)
      8 
      9     def __set__(self, obj, val):

AttributeError: 'NoneType' object has no attribute 'read'

第二个问题是,Ipython只在描述符是property (硬编码)的实例时才使用描述符进行帮助。这方面的逻辑是这里

要修复第一个问题,如果描述符为obj传递None,则希望返回描述符本身:

代码语言:javascript
复制
    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        ...

要解决第二个问题,要么需要向ipython提交修补程序,要么需要从属性中提交子类(虽然有点麻烦,但要容易得多)。把它们放在一起:

代码语言:javascript
复制
class Register(property):
    def __init__(self, address, docstring="instance docstring"):
        self.address = address    
        self.__doc__ = docstring

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        return obj.read(self.address)

    def __set__(self, obj, val):
        return obj.write(self.address, val)
        

class Interface(object):
    r = Register(0x00, docstring="the first register")

i = Interface()

然后在ipython中,您可以得到:

代码语言:javascript
复制
In [21]: i.r?
Type:        Register
String form: <__main__.Register object at 0x1051203a0>
Docstring:   the first register
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37255109

复制
相关文章

相似问题

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