在 Python 中使用 class 属性修改带装饰器的文档字符串
Using class attributes to modify a docstring with a decorator in Python
我正在尝试创建一个在 class 中调用的装饰器,它将从 class 中提取属性,并使用这些 class 属性来编辑函数的文档字符串.
我的问题是我找到了编辑函数文档字符串的装饰器示例(将函数的 __doc__
属性设置为新字符串),我还找到了提取属性的装饰器示例来自父级 class(通过将 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
有了这个,我希望以下内容会 return "Docstring is now new for the function: example":
Test().example.__doc__
而是 returns None
.
编辑: 请注意,我对如何具体访问 class 的名称不感兴趣,更不用说如何访问 class一般属性(此处以 self.__class__.__name__
为例)。
example
替换为wrapper
;装修相当于
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
时,您没有任何关于 class 修饰的 function/method 属于什么的信息。您必须明确传递其名称:
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__
属性的第一个标记来获取class姓名:
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
事实证明,从 class 中访问 class 属性是不可能的,因为在调用装饰器时 class 尚未执行。所以最初的目标 - 在 class 中使用装饰器来访问 class 属性 - 似乎是不可能的。
但是,感谢 jdehesa 为我指出了一种解决方法,允许使用 class 装饰器访问 class 属性,此处:Can a Python decorator of an instance method access the class?。
我能够使用 class 装饰器使用 class 属性更改特定方法的文档字符串,如下所示:
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"
我正在尝试创建一个在 class 中调用的装饰器,它将从 class 中提取属性,并使用这些 class 属性来编辑函数的文档字符串.
我的问题是我找到了编辑函数文档字符串的装饰器示例(将函数的 __doc__
属性设置为新字符串),我还找到了提取属性的装饰器示例来自父级 class(通过将 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
有了这个,我希望以下内容会 return "Docstring is now new for the function: example":
Test().example.__doc__
而是 returns None
.
编辑: 请注意,我对如何具体访问 class 的名称不感兴趣,更不用说如何访问 class一般属性(此处以 self.__class__.__name__
为例)。
example
替换为wrapper
;装修相当于
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
时,您没有任何关于 class 修饰的 function/method 属于什么的信息。您必须明确传递其名称:
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__
属性的第一个标记来获取class姓名:
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
事实证明,从 class 中访问 class 属性是不可能的,因为在调用装饰器时 class 尚未执行。所以最初的目标 - 在 class 中使用装饰器来访问 class 属性 - 似乎是不可能的。
但是,感谢 jdehesa 为我指出了一种解决方法,允许使用 class 装饰器访问 class 属性,此处:Can a Python decorator of an instance method access the class?。
我能够使用 class 装饰器使用 class 属性更改特定方法的文档字符串,如下所示:
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"