簡體   English   中英

在Python中使用類屬性通過修飾符修改文檔字符串

[英]Using class attributes to modify a docstring with a decorator in Python

我正在嘗試創建在類中調用的裝飾器,該裝飾器將從該類中提取屬性,並使用這些類屬性來編輯函數的文檔字符串。

我的問題是,我找到了裝飾器的示例,這些修飾器可以編輯函數的文檔字符串(將函數的__doc__屬性設置為新的字符串),並且我還可以找到裝飾器的示例,這些裝飾器可以從父類中提取屬性(通過將self傳遞給裝飾器),但我還無法找到一個能夠同時實現這兩個功能的裝飾器示例。

我試圖結合這兩個例子,但是沒有用:

def my_decorator(func):
    def wrapper(self, *args, **kwargs):
        name = func.__name__  # pull function name
        cls = self.__class__.__name__ # pull class name
        func.__doc__ = "{} is new for the function {} in class {}".format(
            str(func.__doc__), name, cls) # set them to docstring
        return func(self, *args, **kwargs)
    return wrapper

class Test():
    @my_decorator
    def example(self, examplearg=1):
        """Docstring"""
        pass

有了這個,我希望以下代碼將返回“該函數的文檔字符串現在是新的:示例”:

Test().example.__doc__

相反,它返回None

編輯:請注意,我對如何訪問類的名稱不感興趣,而是對如何訪問類的一般屬性不感興趣(此處以self.__class__.__name__為例)。

examplewrapper代替; 裝飾相當於

def example(self, examplearg=1):
    """Docstring"""
    pass

 example = my_decorator(example)

因此,您需要設置wrapper.__doc__ ,而不是func.__doc__

def my_decorator(func):
    def wrapper(self, *args, **kwargs):
        return func(self, *args, **kwargs)
    wrapper.__doc__ = "{} is new for the function {}".format(
        str(func.__doc__),
        func.__name__) 
    return wrapper

請注意,在調用my_decorator ,您沒有關於修飾后的函數/方法屬於哪個類的任何信息。 您將必須明確傳遞其名稱:

def my_decorator(cls_name):
    def _decorator(func):
        def wrapper(self, *args, **kwargs):
            return func(self, *args, **kwargs)
        wrapper.__doc__ = "{} is new for function {} in class {}".format(
            func.__doc__, 
            func.__name__,
            cls_name)
       return wrapper
    return _decorator

class Test():
    @my_decorator("Test")
    def example(self, examplearg=1):
        """Docstring"""

    # or
    # def example(self, examplearg=1):
    #     """Docstring"""
    #
    # example = my_decorator("Test")(example)

您可以在調用裝飾器時簡單地修改__doc__屬性,並使用該函數的以點分隔的__qualname__屬性的第一個標記來獲取類名:

def my_decorator(func):
    func.__doc__ = "{} is new for the function {} in class {}".format(
            str(func.__doc__), func.__name__, func.__qualname__.split('.')[0])
    return func

以便:

class Test():
    @my_decorator
    def example(self, examplearg=1):
        """Docstring"""
        pass
print(Test().example.__doc__)

將輸出:

Docstring is new for the function example in class Test

事實證明,無法從類內部訪問類屬性,因為在調用裝飾器時尚未執行該類。 因此,最初的目標-在類中使用裝飾器訪問類屬性-似乎是不可能的。

但是,感謝jdehesa向我指出了一種允許使用類裝飾器訪問類屬性的解決方法,這里: 實例方法的Python裝飾器可以訪問該類嗎?

我可以使用類裝飾器使用類屬性來更改特定方法的文檔字符串,如下所示:

def class_decorator(cls):
    for name, method in cls.__dict__.items():
        if name == 'example':
            # do something with the method
            method.__doc__ = "{} is new for function {} in class {}".format(method.__doc__, name, cls.__name__)
            # Note that other class attributes such as cls.__base__ 
            # can also be accessed in this way
    return cls

@class_decorator
class Test():
    def example(self, examplearg=1):
        """Docstring"""

print(Test().example.__doc__)
# Returns "Docstring is new for function example in class Test"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM