Python:将所有函数包装在一个库中

标签 python wrapper

我们使用另一个内部团队提供的库。 (摇摇欲坠的类比现在开始)

from externalTeam import dataCreator
datacreator.createPizza()
datacreator.createBurger()
datacreator.createHotDog()

最近我们发现他们的一个方法在某些情况下需要一分钟以上的时间来执行。为了调试它,我必须进入我们的代码并在每次调用此方法时添加超时。

import time
from externalTeam import dataCreator
start = time.clock()
datacreator.createPizza()
stop = time.clock()
print "It took %s seconds to perform createPizza" % (str(stop-start))

事后看来,那是因为我们到处都在调用 createPizza,而我们并不控制 createPizza 本身(类比在这里开始有点不成立了)。我宁愿只在一个地方调用 createPizza,并能够围绕它添加一个计时器。我的第一个想法是在我自己的包装类中创建一个包装他们所有的方法。不过,这与 DRY 相反,每当他们添加另一种方法时,我都必须更新我们的库来包装它:

import time
from externalTeam import dataCreator
def createPizza(self):
    start = time.clock()
    datacreator.createPizza()
    stop = time.clock()
    print "It took %s seconds to perform createPizza" % (str(stop-start))

def createBurger(self):
    start = time.clock()
    datacreator.createPizza()
    stop = time.clock()
    print "It took %s seconds to perform createBurger" % (str(stop-start))

def createHotDog(self):
    start = time.clock()
    datacreator.createPizza()
    stop = time.clock()
    print "It took %s seconds to perform createHotDog" % (str(stop-start))    

我想要的是一种始终围绕从 dataCreator 调用的每个函数执行几行代码的方法。必须有一些方法可以通过一个中间类来做到这一点,该中间类的方法可以动态定义——或者更确切地说是未定义的,对吧?

最佳答案

我会创建一个像这样工作的 dataCreator 适配器类:

  1. 有一个 methods2wrap 列表,其中包含来自 dataCreator 的方法,需要将其包装到调试/计时功能中。
  2. 有一个重写的 __getattribute__() 将 1:1 映射到 dataCreator 方法,将 methods2wrap 中的方法包装到计时调试中消息。

概念验证代码(该示例包装类 list 并在其方法 append 周围插入调试时间戳)。

import time

class wrapper(list):

    def __getattribute__(self, name):
        TO_OVERRIDE = ['append']
        if name in TO_OVERRIDE:
            start = time.clock()
        ret = super(list, self).__getattribute__(name)
        if name in TO_OVERRIDE:
            stop = time.clock()
            print "It took %s seconds to perform %s" % (str(stop-start), name)
        return ret

profiled_list = wrapper('abc')
print profiled_list
profiled_list.append('d')
print profiled_list
profiled_list.pop()
print profiled_list

当然,您可以在此示例的基础上构建并使其参数化,以便在初始化时您可以设置要包装的类以及应计时的方法...

编辑:请注意,TO_OVERRIDE 会在每次 __getattribute__ 调用时重新分配。这是设计使然。如果你将它作为类属性,__getattribute__ 将递归循环(你应该使用对父 __getattribute__ 方法的显式调用来检索它,但这可能是比从头开始重建列表要慢。

HTH

关于Python:将所有函数包装在一个库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6602256/

相关文章:

python - python 服务器包装器的示例代码

java - Java 中对象的动态类型转换

Python:是否有快捷方式来查找哪个子字符串(来自一组子字符串)在字符串中排在第一位?

python - 向量元组列表 --> 两个矩阵

python - 使用 xlwings 将 Excel 打印为 pdf

桌面应用程序的 Webkit 包装器

python - 如何使用python客户端访问远程服务器上的Hive

python - 选择所有年份都有观察值的行 python

python - 将 Python 的输入输入到 C++ 程序中

Java Wrapper 相等性测试