python - 使用 getattr 获取包含在描述符中的方法

标签 python descriptor

我有以下描述符,它在调用使用 @saveconfig 注释的方法后将配置保存在类中:

class saveconfig(object):
    def __init__(self, f):
        self.f = f

    def __get__(self, instance, owner):
        def wrapper(*args):
            self.f(instance, *args)
            instance.cfg.write()
            instance.paramcfg.write()
        return wrapper

它的用法如下:

class pbtools():
    @saveconfig
    def getip(self, ip):
        (...)

效果很好。现在我想通过使用 getattr 来获取装饰方法。但由于该方法是由描述符包装的,因此我只得到 wrapper 结果:

pbt = pbtools()
# results in "<function wrapper at 0x23cced8>:"
method = getattr(pbt, "getip")

我如何使用 getattr 访问包装的方法 getip ,以便能够通过它的名称调用它? (当然我不能直接访问该方法,否则我就不必这样做)。

附加说明:

该脚本是从命令行调用的。我必须将命令行参数(字符串)映射到具有相同名称的方法才能调用它。此外,我必须将任何其他参数从命令行映射到方法的参数,如下所示:

pbtools getip 192.168.178.123 #-> calls getip with parameter 192.168.178.123

由于我无法获取原始方法,因此我不知道它有多少参数来映射它们。我有几个像这样装饰的方法,因为我想将保存配置的横切关注点移出 pbtools 类中的方法。

最佳答案

我仍然不能 100% 确定我完全理解您的问题。你说“因为我无法获得原始方法,所以我不知道它有多少参数来映射它们”,但是你不需要访问原始方法来通过可变数量的参数调用(因为装饰器有*args)。你可以这样做:

import sys
cmd = sys.argv[1]
params = sys.argv[2:]

pbt = pbtools()

func = getattr(pbt, cmd)
func(*params)

您还可以稍微简化您的装饰器。它实际上并不需要 __get__ 机制。

import functools

def saveconfig(f):
    @functools.wraps(f)
    def wrapper(self, *args):
        f(self, *args)
        self.cfg.write()
        self.paramcfg.write()
    return wrapper

functools.wraps 是一个辅助装饰器,它使包装器模仿原始函数(即它复制函数名称、文档字符串和类似的东西)。它将使调试更容易,因为您将知道异常源自何处等。

关于python - 使用 getattr 获取包含在描述符中的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5020210/

相关文章:

python - 根据最大长度格式化字符串

具有两个字符串的 Python 函数 - 子字谜

python - 按时间段迭代数据帧 block

python - 从外部 qss 文件读取 pyqt 样式表

python - 如何在子类中使用描述符的装饰器

Python 描述符 __get__ 和 __set__

Python PDFMiner 错误 : "No/Root object! - Is this really a PDF?"

描述符的 Python 元编程 : How to add descriptor after class definition?

python - 如何在 Python 2.7 中用另一个类修饰实例方法?