因此,如果我有一个使用方法foo
的类:
class A(object):
def __init__(self, name, age):
self.name = name
self.age = age
def foo(self):
return "Hey I am called %s." % self.name
我决定做一个包装:
def bar(obj, func):
def inner(*args, **kwargs):
print "I am %d years old." % obj.age
return func(*args, **Kwargs)
return inner
然后,我继续在
obj.foo
类的实例上替换A
,一切都很好。Stick = A('Stick', 32)
Stick.foo = bar(Stick, Stick.foo)
Stick.foo()
>>> I am 32 years old.
>>> Hey I am called Stick.
这样就可以了,但是如果我省略了
return func(*args, **kwargs)
位,它的作用就好像它只是以与使用types.MethodType
快速替换实例方法时所期望的方式替换方法一样。def bar(obj):
def inner(*args, **kwargs):
return "I am %d years old." % obj.age
return inner
Stick.foo = bar(Stick)
Stick.foo()
>>> I am 32 years old.
因此,也许这种方式会产生某种开销,或者这种实施策略模式的方式也会带来其他缺陷,但是……这似乎效果很好。与出于编写其中包含单词
types.MethodType
的功能而引入self
相比,我不清楚为什么为什么导入types.MethodType
而不是仅使用不返回原始方法的包装程序更受欢迎? ,或使用分配语法而不是@decorator的处理方式。我觉得我经常看到使用
types
库的建议,该库似乎在某人似乎想要某种策略模式的情况下-并非总是如此,但经常出现在很多用户可能忽略了Python似乎已经具备的功能的地方处理。就像在this speech from PyCon 2009中,给出了清晰的示例,敦促编码人员“先寻找语言”以寻求在进行更改之前可能已经存在的功能-我相信他的演讲的重点更多是针对过度编码或出并编写PEP,但我认为它也适用于此-当只需要包装器时,是否应该转向图书馆?因此,除非有某种使
types
方法更具吸引力的方法,在这种情况下答案很明显,这就是我要问的问题:在哪种情况下,首选使用types.MethodType
而不是简单地编写包装器像我展示的那样? 最佳答案
尽管我会承认过去曾经为flexmock子类化types
,但您很少需要或想要在types.ModuleType
模块中使用任何东西的情况很少发生。该模块的主要目的主要是为您提供类的名称,否则这些类将很难引用,但需要注意的是,某些类也被诸如dict
或int
之类的东西所熟知。
实际上,很少真正需要使用这些名称来构造或子类化某些东西。那么,您如何处理types.MethodType
之类的东西?使用它进行内省。
假设您想编写一个自动文档生成器。也许您将问题自动交给模块。使用types.FunctionType
,types.TypeType
以及可能的types.ClassType
(对于旧式类),您可以找出模块中的什么是函数和类,并为每个函数和类调用适当的文档格式化程序。对于每个类,您可以遍历其成员,并使用types.MethodType
从其其他属性中整理出该类的方法,并适当地记录每个方法。
关于python - 如果包装程序可以替换实例方法,为什么还要使用types.MethodType?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22433249/