Get方法包装在一个带有g的描述符中

2024-09-27 22:39:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下描述符,它在调用带@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

它的用法是这样的:

^{pr2}$

它工作得很好。现在我想使用getattr来获得装饰方法。但是由于方法是由描述符包装的,因此我只得到wrapper

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

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

附加说明:

脚本从命令行调用。我必须将一个命令行参数(string)映射到一个同名的方法来调用它。此外,我必须将comamndline中的任何附加参数映射到方法的参数,如下所示:

pbtools getip 192.168.178.123 #-> calls getip with parameter 192.168.178.123

因为我不能得到原始方法,我不知道有多少参数需要映射它们。我有几个这样修饰的方法,因为我想把保存配置的横切关注点从pbtools类的方法中移出。在


Tags: 方法instance命令行self参数defargswrapper
2条回答

首先,对于我的错误的评论我很抱歉,现在你的最后一段代码将不能像你一样工作(你的方法不再被修饰),因为要理解decorator,你必须看到以下内容:

class pbtools():
    @saveconfig
    def getip():
        (...)

相当于:

^{pr2}$

在您的最新例子中saveconfigreturn self.f,在我们的代码中等于getip,所以在本例中,这段代码:

getip = saveconfig(getip)

相当于:

 getip = getip

所以基本上它什么也不做。在

解决方法是将包装好的函数保存在包装函数中,如下所示:

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()

        wrapper.func = self.f    # Create a new attribute and assign it to the wrapped func.
        return wrapper

现在您可以:

class pbtools():
    @saveconfig
    def getip():
        print "hi"

pbt = pbtools()
method = getattr(pbt, "getip")
print method.func
# <function getip at 0x2363410>
method.func()
# hi

希望这能有所帮助:)

我还是不能完全理解你的问题。你说“因为我不能得到原始方法,我不知道它有多少参数来映射它们”,但是你不需要访问原始方法来通过可变数量的参数来调用(因为decorator有*args)。你可以这样做:

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

pbt = pbtools()

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

你也可以简化一下你的装饰师。它不需要__get__机制。在

^{pr2}$

functools.wraps是一个帮助修饰符,它使包装器模仿原始函数(即,它复制函数名、docstring等类似内容)。这将使调试更容易,因为您将知道异常是从哪里起源的etc

相关问题 更多 >

    热门问题