如何用Python或函数式编程语言创建函数扩展/函数接口/函数类?
我想定义一些东西,最好在Python中调用“函数扩展”/“函数接口”或“函数类”。我还没有在其他语言中见过类似的构造,但我不擅长LISP之类的函数式语言。如果这更容易做到,考虑以后改用其他语言,比如Julia “函数扩展”将是一种形式化的方式来表示绑定函数的几个参数,我们最终得到一个属于特定“函数类”的函数。在我下面的示例中,特定的“函数类”是一个数据转换函数(如如何用Python或函数式编程语言创建函数扩展/函数接口/函数类?,python,types,lambda,functional-programming,lambda-calculus,Python,Types,Lambda,Functional Programming,Lambda Calculus,我想定义一些东西,最好在Python中调用“函数扩展”/“函数接口”或“函数类”。我还没有在其他语言中见过类似的构造,但我不擅长LISP之类的函数式语言。如果这更容易做到,考虑以后改用其他语言,比如Julia “函数扩展”将是一种形式化的方式来表示绑定函数的几个参数,我们最终得到一个属于特定“函数类”的函数。在我下面的示例中,特定的“函数类”是一个数据转换函数(如transform\u data\u func\u class),它只有一个参数:datapower\u data扩展了transfo
transform\u data\u func\u class
),它只有一个参数:data
power\u data
扩展了transform\u data\u func\u类
作为绑定指数
参数,我们最终得到了一个属于“函数类”的函数transform\u data\u func\u类
“函数类”定义了签名的一部分,如:
def transform_data_func_class(data):
raise InterfaceError('Called unimplemented function class.')
然后将定义扩展“函数类”的函数:
def power_data(data, exponent): # extends: transform_data_func_class
return data ** exponent # apply the additional the parameter
square = partial(power_data, exponent=2) # matches signature transform_data_func_class(data)
因此,当绑定附加参数时,我们最终得到一个与扩展“函数类”匹配的签名:
def power_data(data, exponent): # extends: transform_data_func_class
return data ** exponent # apply the additional the parameter
square = partial(power_data, exponent=2) # matches signature transform_data_func_class(data)
例如,为了将函数类型指定为其他函数的输入和输出,我将使用这些函数:
def chain(data, transform_data_func_class_list):
"""Passing in data and a list of functions being elements of
transform_data_func_class with a sole argument: data."""
...
奇怪的是,在一般对象的情况下,定义类/类型相对容易,而在函数的情况下,没有这样明显的构造。目前,我使用extends:function\u class
注释来指定函数类型/类-这是从mypy
中借用的想法-理想情况下会使用更正式的东西
欢迎任何建议,如果我可以通过\uuuuu call\uuuu
调用生成的构造,那就太好了。我曾经想过这样一门课:
class TransformDataFuncClass(object):
@classmethod
def exec(cls, data):
raise InterfaceError('Called unimplemented function class.')
但我不喜欢不常用的exec()调用。还想到:
class TransformDataFuncClass(object):
@classmethod
def __call__(cls, data):
raise InterfaceError('Called unimplemented function class.')
但是我得到了TypeError:object()在调用TransformDataFuncClass(data=1)
时不接受任何参数。不过,通过类继承发出“函数扩展”信号将是一种很好的方式
我最详细的计划是:
class FuncClass(object):
"""Takes care of function classes and extensions being
just callable through __call__, e.g. PowerData(data=1, power=2)
instead of instantiating first: PowerData()(data=1, power=2)"""
def __init__(self, wrapped_class):
self.wrapped_class = wrapped_class
self.wrapped_instance = wrapped_class()
def __call__(self, *args, **kwargs):
return self.wrapped_instance(*args, **kwargs)
@FuncClass
class TransformDataFuncClass(object):
def __call__(self, data):
raise InterfaceError('Called unimplemented function class.')
@FuncClass
class PowerData(TransformDataFuncClass.wrapped_class):
def __call__(self, data, exponent):
return data ** exponent # apply the additional the parameter
因此TransformDataFuncClass(data=1)
和PowerData(data=1,exponent=2)
是自然有效的调用。虽然后者实际上工作起来有点复杂,而且无法并行计算,因为我从dill
(一个比pickle
更聪明的选择)那里得到了错误,说:它与PowerData
不是同一个对象
欢迎任何建议,真的。我还对理论上的考虑以及如何在其他语言中实现这一点感兴趣。很难看出您想要实现什么。具体而言,对于这两个函数定义:
def transform_data_interface(data):
raise InterfaceError('Called unimplemented interface.')
def power_data(data, param1): # extends: transform_data_interface
return data ** param1 # apply the additional the parameter
power\u data
如何扩展transform\u data\u接口
?它们没有相同的签名:“接口”使用一个参数,而实现接口的函数使用两个参数。这与大多数人会说的是一个错误不符
如果您要做的是强制一个给定函数与另一个函数具有相同的参数和返回值,那么您可以通过检查函数的参数来实现这一点
- stdlib中的模块可以告诉您函数接受哪些参数,具体来说,它提供了一个很好的API
- 允许您标记函数的参数和返回值,这可能会取代您尝试使用
“#extends:”
注释所做的操作
- 另请参见和
- decorator是添加此类检查的最佳场所,因为它在函数执行之前包装函数,所以很多人都制作了类型检查decorator(示例:,)
有关链的功能,请参阅。您可以修改其中的一个来执行我上面提到的那种检查
至于其他功能性更强的语言是如何做到这一点的,我不确定。我在上面链接的那篇界面文章中看到了,看起来那里有一些很好的信息
如果你有更多的细节或背景,请更新你的帖子 这与函数重载有何不同?我需要几个具有相同(或扩展)签名且名称不同的函数。“函数重载或方法重载是使用不同的实现创建相同名称的多个方法的能力”。假设multilydata(data,param1)
与PowerData(data,param1)
具有相同的签名。我所寻找的更像是对象的接口/抽象类。一旦你修复了一个类的移动部分,它将匹配继承的接口。当然有点超出了m,e,我的第一反应是建议一个元类,但我肯定我没有完全理解这个概念-这可能是一个开始。。。谢谢你的建议,我改进了我的整个解释,并添加了第二段,希望能解释得更清楚。Mypy是一个伟大的项目,而我正在使用Python 2.7,迫不及待地想升级到3@MarkHorvath,《迷失理论》的答案让我找到了Python食谱,这本书可能会给你一些想法:@wwii,我自己也应该使用ABCs。检查可能是严格允许某个签名的函数作为参数的方法。尽管如此,我更需要的是一种在代码中表达签名类型系统的方法。。。我将尝试更多,也许这只是我不了解的关于dill
序列化的一件小事。