为了得到你想要的东西,你必须为你的函数写一个非数据描述符和一组包装类。原因在于从对象获取函数的过程是高度优化的,并且不可能劫持这种机制。相反,您必须编写自己的模拟此机制的类 - 如果您正在进行大量小型方法调用,则会降低代码速度。
我认为获得所需功能的最佳方式不是使用您描述的任何方法,而是编写一个在需要调用标准格式的普通函数时使用的包装函数。例如。
def vectorise(method, *args, **kwargs):
return tuple(method(arg, **kwargs) for arg in args)
obj = _SomeClass()
result = vectorise(obj.add_one, 1, 2, 3)
事实上,这是多么numpy
需要上一个参数操作功能,并把它们成列上工作的功能。
import numpy
def add_one(x):
return x + 1
arr = numpy.vectorize(add_one)([1, 2, 3])
如果你确实真的想要使用非数据描述符,那么下面的工作将会起作用。被警告这些方法调用相当慢。在我的计算机上,一个普通的方法调用需要188纳秒,而对于“简单”方法调用则需要1.53微秒 - 相差10倍。和vectorise
通话需要一半的时间拨打standard_form
。那时绝大多数是查找方法。实际的方法调用非常快。
class simple_form:
"""Allows a simple function to be called in a standard way."""
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
if instance is None:
return self.func
return SimpleFormMethod(self.func, instance)
class MethodBase:
"""Provides support for getting the string representation of methods."""
def __init__(self, func, instance):
self.func = func
self.instance = instance
def _format(self):
return "<bound {method_class} {obj_class}.{func} of {obj}>".format(
method_class=self.__class__.__name__,
obj_class=self.instance.__class__.__name__,
func=self.func.__name__,
obj=self.instance)
def __str__(self):
return self._format()
def __repr__(self):
return self._format()
class SimpleFormMethod(MethodBase):
def __call__(self, *args, **kwargs):
return self.func(self.instance, *args, **kwargs)
@property
def standard_form(self):
return StandardFormMethod(self.func, self.instance)
class StandardFormMethod(MethodBase):
def __call__(self, *args, **kwargs):
return tuple(self.func(self.instance, arg, **kwargs) for arg in args)
class Number(object):
def __init__(self, value):
self.value = value
def add_to(self, *values):
return tuple(val + self.value for val in values)
@simple_form
def divide_into(self, value):
return value/self.value
num = Number(2)
print("normal method access:", num.add_to, sep="\n")
print("simple form method access:", num.divide_into, sep="\n")
print("standard form method access:", num.divide_into.standard_form, sep="\n")
print("access to underlying function:", Number.divide_into, sep="\n")
print("simple example usage:", num.divide_into(3))
print("standard example usage:", num.divide_into.standard_form(*range(3)))
为什么在这里标记theano? – eickenberg 2014-11-04 08:41:34
请参阅底部的注释 - 问题源于事实:在theano中,您需要表示返回值中的任何状态更改。 – Peter 2014-11-04 18:47:03
感谢和抱歉,我应该刚刚为word – eickenberg 2014-11-04 19:49:49