爲了得到你想要的東西,你必須爲你的函數寫一個非數據描述符和一組包裝類。原因在於從對象獲取函數的過程是高度優化的,並且不可能劫持這種機制。相反,您必須編寫自己的模擬此機制的類 - 如果您正在進行大量小型方法調用,則會降低代碼速度。
我認爲獲得所需功能的最佳方式不是使用您描述的任何方法,而是編寫一個在需要調用標準格式的普通函數時使用的包裝函數。例如。
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