Python装饰类文档

我正在使用装饰器处理python中的单例,如下所示。

我希望装饰类的pydoc与非装饰类的pydoc完全相同,但是我不知道怎么做:

  • 没有getSingletonInstance.__doc__ = cls.__doc__行,修饰类的pydoc给出了singleton函数的pydoc。

  • getSingletonInstance.__doc__ = cls.__doc__行中,修饰类的pydoc仅提供“顶级”文档字符串。

我该如何进行?

谢谢。

def singleton(cls):
    """A singleton decorator

    Warnings
    --------
    Singleton gdecorated calsses cannot be inhehited

    Example
    -------
    >>> from decorators import singleton
    >>> @singleton
    ... class SingletonDemo():
    ...     pass
    >>> d1 = SingletonDemo()
    >>> d1.a = 0xCAFE
    >>> d2 = SingletonDemo()
    >>> id(d1) == id(d2)
    True
    >>> d1 == d2
    True
    >>> d2.a == 0xCAFE
    True

    References
    ----------
    See case 2 of https://www.python.org/dev/peps/pep-0318/#examples
    """
    _instances = {}

    def getSingletonInstance():
        if cls not in _instances:
            _instances[cls] = cls()
        return _instances[cls]

    getSingletonInstance.__doc__ = cls.__doc__

    return getSingletonInstance
yndf345678 回答:Python装饰类文档

尝试使用functools.wraps

import functools

def wrapper(cls):
    _instances = {}
    class inner(cls):
        def __new__(subcls):
            if subcls not in _instances:
                _instances[subcls] = object.__new__(subcls)
            return _instances[subcls]
    inner.__doc__=cls.__doc__
    return inner

@wrapper
class A(object):
    """Example Docstring"""
    def method(self):
        """Method Docstring"

A.__doc__
# "Example Docstring"
A.method.__doc__
# "Method Docstring"
,

用示例总结所有讨论。 非常感谢大家。

此解决方案:

  • 保留文档字符串
  • 保留类型
  • 支持静态和类方法

限制:

  • 不能继承子集,这对于上下文是有意义的

解决方案:     def singleton(cls):

    """A singleton decorator

    Warnings
    --------
    Singleton decorated classes cannot be inhehited

    Example
    -------
    >>> import abc
    >>> 
    >>> @singleton
    ... class A():
    ...     "Ad-hoc documentation of class A"
    ...     def __init__(self):
    ...         "Ad-hoc documentation of class A constructor"
    ...         print("constructor called")
    ...         self.x = None
    ...     @classmethod
    ...     def cm(cls):
    ...         "a class method"
    ...         print("class method called")
    ...     def im(self):
    ...         "an instance method"
    ...         print("instance method called")
    ...     @staticmethod
    ...     def sm():
    ...         "a static method"
    ...         print("static method called")
    ... 
    >>> @singleton
    ... class P(abc.ABCMeta):
    ...     @abc.abstractmethod
    ...     def __init__(self):
    ...         pass
    ... 
    >>> class C(P):
    ...     def __init__(self):
    ...         print("C1 constructor called")
    ... 
    >>> a1 = A()
    constructor called
    >>> a1.x = 0xCAFE
    >>> a1.x
    51966
    >>> a2 = A()
    >>> a2.x
    51966
    >>> a1.x == a2.x
    True
    >>> a1 == a2
    True
    >>> id(a1) == id(a2)
    True
    >>> type(a1) == type(a2)
    True
    >>> isinstance(a1,A)
    True
    >>> ta1 = type(a1)
    >>> issubclass(ta1,A)
    True
    >>> A.cm()
    class method called
    >>> a1.cm()
    class method called
    >>> A.sm()
    static method called
    >>> a1.sm()
    static method called
    >>> a1.im()
    instance method called
    >>> try:
    ...     C()
    ... except Exception as e:
    ...     type(e)
    ... 
    <class 'TypeError'>

    """
    _instances = {}
    _constructorCalled = []
    class inner(cls):
        def __new__(subcls):
            if subcls not in _instances:
                _instances[subcls] = cls.__new__(subcls)
            return _instances[subcls]
        def __init__(self):
            if type(self) not in _constructorCalled:
                cls.__init__(self)
                _constructorCalled.append(type(self))
        __init__.__doc__ = cls.__init__.__doc__
        __new__.__doc__ = cls.__new__.__doc__
        if __new__.__doc__ == (
            "Create and return a new object.  "
            "See help(type) for accurate signature."
        ):
            __new__.__doc__ = "Returns a singleton instance"
    inner.__doc__ = cls.__doc__
    return inner
本文链接:https://www.f2er.com/3153889.html

大家都在问