Python 如何获取用 property.setter 包装的方法__qualname__



我有一个实例属性,我使用 Python 的property装饰器创建了一个属性。

然后,我使用装饰器@property_name.setter为该物业制作了一个设置器。

如何获得用@property.setter修饰的原始方法定义的__qualname__


我看过的地方

  • Python:使用装饰器__qualname__函数
    • 我不认为property使用@functools.wraps()
  • Python @property.setter
    • 我意识到property实际上是一个descriptor
  • 在@property后修饰类方法
    • 告诉我我可能想使用__get__,但我无法弄清楚语法

示例代码

这是用Python 3.6写的.

#!/usr/bin/env python3

def print_qualname():
"""Wraps a method, printing its qualified name."""
def print_qualname_decorator(func):
# print(f"func = {func} and dir(): {dir(func)}")
if hasattr(func, "__qualname__"):
print(f"Qualified name = {func.__qualname__}.")
else:
print("Doesn't have qualified name.")
return print_qualname_decorator

class SomeClass:
def __init__(self):
self._some_attr = 0
self._another_attr = 0
@property
def some_attr(self) -> int:
return self._some_attr
@print_qualname()
@some_attr.setter
def some_attr(self, val: int) -> None:
self._some_attr = val
@print_qualname()
def get_another_attr(self) -> int:
return self._another_attr

输出:

Doesn't have qualified name.
Qualified name = SomeClass.get_another_attr.

如何从print_qualname装饰器内部获取some_attr__qualname__? 换句话说,如何输出SomeClass.some_attr

您可以翻转二传手装饰器的顺序。请注意,我已经调整了print_qualname_decorator以调用基础函数并返回它(否则 setter 将不会执行(。

from functools import wraps
def print_qualname(func):
"""Wraps a method, printing its qualified name."""
@wraps(func)
def print_qualname_decorator(*args):
if hasattr(func, "__qualname__"):
print(f"Qualified name = {func.__qualname__}.")
else:
print("Doesn't have qualified name.")
return func(*args)
return print_qualname_decorator

class SomeClass:
def __init__(self):
self._some_attr = 0
self._another_attr = 0
@property
def some_attr(self) -> int:
return self._some_attr
@some_attr.setter
@print_qualname
def some_attr(self, val: int) -> None:
self._some_attr = val
@print_qualname
def get_another_attr(self) -> int:
return self._another_attr

In [46]: foo = SomeClass()                                               
In [47]: foo.get_another_attr()                                          
Qualified name = SomeClass.get_another_attr.
Out[47]: 0
In [48]: foo.some_attr = 5                                               
Qualified name = SomeClass.some_attr.
In [49]: foo._some_attr                                                  
Out[49]: 5

最新更新