当前位置: 首页 > 面试题库 >

创建包装器类以围绕现有函数调用pre和post函数吗?

荣沈义
2023-03-14
问题内容

我想创建一个包装另一个类的类,以便在通过包装类运行某个函数时,也可以运行pre和post函数。我希望包装器类无需修改即可与任何类一起使用。

例如,如果我有此类。

class Simple(object):
    def one(self):
        print "one"

    def two(self,two):
        print "two" + two

    def three(self):
        print "three"

我可以这样使用…

number = Simple()
number.one()
number.two("2")

到目前为止,我已经编写了这个包装器类…

class Wrapper(object):
    def __init__(self,wrapped_class):
        self.wrapped_class = wrapped_class()

    def __getattr__(self,attr):
        return self.wrapped_class.__getattribute__(attr)

    def pre():
        print "pre"

    def post():
        print "post"

我可以这样称呼…

number = Wrapper(Simple)
number.one()
number.two("2")

除了更改第一行之外,可以使用与上述相同的方法。

我想发生的事情是,通过包装类调用函数时,先调用包装类中的pre函数,然后再调用包装类中的所需函数,然后再调用post函数。我希望能够做到这一点,而无需更改包装的类,也无需更改函数的调用方式,而仅更改类实例的创建方式。例如number
= Simple()vs number = Wrapper(Simple)


问题答案:

差不多了,您只需要在内部进行一些自省__getattr__,就可以在原始属性可调用时返回一个新的包装函数:

class Wrapper(object):
    def __init__(self,wrapped_class):
        self.wrapped_class = wrapped_class()

    def __getattr__(self,attr):
        orig_attr = self.wrapped_class.__getattribute__(attr)
        if callable(orig_attr):
            def hooked(*args, **kwargs):
                self.pre()
                result = orig_attr(*args, **kwargs)
                # prevent wrapped_class from becoming unwrapped
                if result == self.wrapped_class:
                    return self
                self.post()
                return result
            return hooked
        else:
            return orig_attr

    def pre(self):
        print ">> pre"

    def post(self):
        print "<< post"

现在使用以下代码

number = Wrapper(Simple)

print "\nCalling wrapped 'one':"
number.one()

print "\nCalling wrapped 'two':"
number.two("2")

结果是:

Calling wrapped 'one':
>> pre
one
<< post

Calling wrapped 'two':
>> pre
two2
<< post


 类似资料:
  • 问题内容: 编辑 : 请参阅此问题底部的我的完整答案。 tl; dr答 :Python具有静态嵌套的作用域。的 静态 方面可以与隐变量声明相互作用,产生非显而易见的结果。 (由于该语言通常具有动态特性,所以这尤其令人惊讶)。 我以为我对Python的作用域规则掌握得很好,但是这个问题使我彻底陷入困境,而我的google-fu让我失败了(这并不令我感到惊讶-请看问题标题;) 我将从一些可以按预期工作

  • 问题内容: 此代码有效: 这两个测试用例基本相同。但是用这样的数组构造一个字符串很麻烦,而且您无法获得静态分析。所以我当时想做的是这样的: 其中孤立的是一个类似于以下内容的辅助函数: 最大的问题是Function.prototype.toString()给您整个功能。有谁知道从函数的字符串表示形式获取函数体的好方法? 更新:PRoberts在问这是什么目的,目的很简单: 问题答案: 我写了一个版本

  • 函数(我们Java中的方法)可以使用fun关键字就可以定义: fun onCreate(savedInstanceState: Bundle?) { } 如果你没有指定它的返回值,它就会返回Unit,与Java中的void类似,但是Unit是一个真正的对象。你当然也可以指定任何其它的返回类型: fun add(x: Int, y: Int) : Int { return x + y } 小

  • 问题内容: 我下面有一个函数,我想使其泛型: 我想创建一个接受Type1或Type2的函数,而无需为每个类型创建一个函数。我怎样才能做到这一点? 问题答案: 以相同的方式进行操作: 游乐场:http : //play.golang.org/p/iO- cbK50BE 。 通过实际返回遇到的任何错误,可以使此功能更好。

  • 问题内容: 我目前正在使用Boost.Python,希望获得一些帮助来解决棘手的问题。 语境 当C 方法/函数暴露给Python时,它需要释放GIL(全局解释器锁)以允许其他线程使用解释器。这样,当python代码调用C 函数时,解释器可以被其他线程使用。现在,每个C ++函数如下所示: 为了通过它来增强python,我这样做: 问题 该方案可以正常工作,但是这意味着没有充分理由依赖。理想情况下,

  • 进入工作空间,点击“创建新函数”,输入函数名称及相关配置信息。 默认运行环境为Python2,内存限制为128M,请注意修改。超时时间请填写1-300之间的任意数值,单位为s。环境变量以键值对形式填写,不填写则默认没有设置环境变量。 默认代码输入方式为在线编辑,示例代码如下: def main(event): return "Hello, world!\n" 创建成功后可以进入函数详情页