Python 中带有自定义文档字符串的方法和 属性 别名
Method and property aliases with custom docstring in Python
我实现了以下装饰器:
class alias(object):
"""
A decorator for implementing method aliases.
"""
def __init__(self, *aliases):
self.aliases = set(aliases)
def __call__(self, obj):
if type(obj) == property:
obj.fget._aliases = self.aliases
else:
obj._aliases = self.aliases
return obj
def aliased(aliased_class):
"""
A decorator for enabling method aliases.
"""
aliased_class_dict = aliased_class.__dict__.copy()
aliased_class_set = set(aliased_class_dict)
for name, method in aliased_class_dict.items():
aliases = None
if (type(method) == property) and hasattr(method.fget, '_aliases'):
aliases = method.fget._aliases
elif hasattr(method, '_aliases'):
aliases = method._aliases
if aliases:
for a in aliases - aliased_class_set:
setattr(aliased_class, a, method)
return aliased_class
下面是我如何使用它们来创建属性和方法的可调用别名的示例:
@aliased
class MyClass(object):
@alias('a')
@property
def alpha(self) -> float:
"""
Returns the value of alpha.
"""
return 2.5
@alias('agt')
def alpha_greater_than(value) -> bool:
"""
Checks whether alpha is greater than the given value.
"""
return self.alpha > value
mc = MyClass()
result = mc.agt(3.0)
# ...
现在我正在打包我的项目并构建文档。目前,别名方法和属性 "inherit" 与原始实体相同的文档字符串。我想知道是否可以在装饰器级别操纵别名实体的文档字符串,使它们看起来像:
This method/property is an alias of X.
您可以直接操作 X.__doc__
例如:
if aliases:
for a in aliases - aliased_class_set:
method.__doc__ = "This function is an alias of %s." % a
setattr(aliased_class, a, method)
但问题是原来的引用X
也会受到影响。所以你最好使用包装器:
def aliased(aliased_class):
"""
A decorator for enabling method aliases.
"""
def wrapper(func):
@functools.wraps(func)
def inner(*args, **kwargs):
return func(*args, **kwargs)
return inner
aliased_class_dict = aliased_class.__dict__.copy()
aliased_class_set = set(aliased_class_dict)
for name, method in aliased_class_dict.items():
aliases = None
if (type(method) == property) and hasattr(method.fget, '_aliases'):
aliases = method.fget._aliases
elif hasattr(method, '_aliases'):
aliases = method._aliases
if aliases:
for a in aliases - aliased_class_set:
wrapped_method = wrapper(method)
wrapped_method.__doc__ = "This function is an alias of %s." % a
setattr(aliased_class, a, wrapped_method)
return aliased_class
并测试:
print(mc.alpha_greater_than.__doc__)
print(mc.agt.__doc__)
输出:
Checks whether alpha is greater than the given value.
This function is an alias of agt.
我实现了以下装饰器:
class alias(object):
"""
A decorator for implementing method aliases.
"""
def __init__(self, *aliases):
self.aliases = set(aliases)
def __call__(self, obj):
if type(obj) == property:
obj.fget._aliases = self.aliases
else:
obj._aliases = self.aliases
return obj
def aliased(aliased_class):
"""
A decorator for enabling method aliases.
"""
aliased_class_dict = aliased_class.__dict__.copy()
aliased_class_set = set(aliased_class_dict)
for name, method in aliased_class_dict.items():
aliases = None
if (type(method) == property) and hasattr(method.fget, '_aliases'):
aliases = method.fget._aliases
elif hasattr(method, '_aliases'):
aliases = method._aliases
if aliases:
for a in aliases - aliased_class_set:
setattr(aliased_class, a, method)
return aliased_class
下面是我如何使用它们来创建属性和方法的可调用别名的示例:
@aliased
class MyClass(object):
@alias('a')
@property
def alpha(self) -> float:
"""
Returns the value of alpha.
"""
return 2.5
@alias('agt')
def alpha_greater_than(value) -> bool:
"""
Checks whether alpha is greater than the given value.
"""
return self.alpha > value
mc = MyClass()
result = mc.agt(3.0)
# ...
现在我正在打包我的项目并构建文档。目前,别名方法和属性 "inherit" 与原始实体相同的文档字符串。我想知道是否可以在装饰器级别操纵别名实体的文档字符串,使它们看起来像:
This method/property is an alias of X.
您可以直接操作 X.__doc__
例如:
if aliases:
for a in aliases - aliased_class_set:
method.__doc__ = "This function is an alias of %s." % a
setattr(aliased_class, a, method)
但问题是原来的引用X
也会受到影响。所以你最好使用包装器:
def aliased(aliased_class):
"""
A decorator for enabling method aliases.
"""
def wrapper(func):
@functools.wraps(func)
def inner(*args, **kwargs):
return func(*args, **kwargs)
return inner
aliased_class_dict = aliased_class.__dict__.copy()
aliased_class_set = set(aliased_class_dict)
for name, method in aliased_class_dict.items():
aliases = None
if (type(method) == property) and hasattr(method.fget, '_aliases'):
aliases = method.fget._aliases
elif hasattr(method, '_aliases'):
aliases = method._aliases
if aliases:
for a in aliases - aliased_class_set:
wrapped_method = wrapper(method)
wrapped_method.__doc__ = "This function is an alias of %s." % a
setattr(aliased_class, a, wrapped_method)
return aliased_class
并测试:
print(mc.alpha_greater_than.__doc__)
print(mc.agt.__doc__)
输出:
Checks whether alpha is greater than the given value.
This function is an alias of agt.