我想定义一个函数集群,可以使用给定的初始参数进行链接和调用,然后获取最终结果,我希望它可以充当Linux命令管道链:
test01() | test02() | test03() | test04()
[init_parameter] ----------------------------------------------------> [final result]
我在考虑可以添加/减少/重新混合的函数序列,例如:
test02() | test03() | test01() | test04()
[init_parameter] ----------------------------------------------------> [final result]
test03()| test01() | test04() | test01()
[init_parameter] ----------------------------------------------------> [final result]
我也希望那些功能可以附带其能力指示器嵌入,可用于预先检测的智能参数,例如,如果输入不是此功能可以接受或输入的类型超过其最大处理能力,链条可以在这个计算流上被忽略而不是使用“try ... except ...”来捕获那些“逻辑”错误。
请参阅下面的代码,未经测试,仅用于描述我的想法:
def test01(f_inspect=false, a, **b):
my_capability = {
"function_cluster": "A01",
"input_acceptable": type([]),
"input_element_acceptable": type(1),
"input_length_max": 100,
"return_type": type([]),
"return_element": type(1),
"return_length_max": 100,
}
if f_inspect:
return my_capability
return [x+1 for x in a] # just sample and may raise error by python such as div 0
def test02(f_inspect=false, a, **b):
# similiar as test01
def test03(f_inspect=false, a, **b):
# similiar as test01
def test04(f_inspect=false, a, **b):
# similar as test01
#==========================================
#test if function chain is compatible
def f_capability_compatible(current_,next_):
return True if
next_["function_cluster"] == current_["function_cluster"] and
next_["input_acceptable"] is current_["return_type"] and
next_["input_length_max"] >= current_["return_element"] and
next_["input_length_max"] >= current_["return_length_max"]
return False
foos = [test01,test02,test03,test04]
from itertools import permutations
mypermutations = permutations(foos, 3) # get permutations of testXX
init_parameter = [x for x in range(1,100)]
dummy_function_parameter = {
"function_cluster": "A01",
"input_acceptable": type([]),
"input_element_acceptable": type(1),
"input_length_max": 100,
"return_type": type([]),
"return_element": type(1)
"return_length_max": 100,
}
chain_flag = [True for x in range(len(mypermutations))]
#[True, True, True, ..... True, True, True, True, True, True, True]
for x in len(mypermutations):
tmp_para = dummy_function_parameter
for y in mypermutations[x]:
test_result = f_capability_compatible(tmp_para,y(f_inspect=true))
chain_flag[x] = test_result
tmp_para = y(f_inspect=true)
if test_result == False :
print "this can not be chained due to parameter incompatible at position %s" %x
break
#==========================================
result_of_chain = []
# to invoke:
for x in len(mypermutations):
if chain_flag[x] == True:
try :
# invoking my_capability[x] chain in a go
tmp_return = init_parameter
for f in mypermutations[x]:
tmp_return = f(tmp_return) #parameter of testXX(a)
except :
result_of_chain[x] = "Error"
else:
result_of_chain[x] = "Incomp"
这是我的问题, 有可能使这个功能链和组合想法更简单吗?
=============================================== ========================================
更新我需要预测参数和返回类型的原因:
在linux命令行中,我们可以使用如下命令:
$ cat sometfile | grep something | awk '{print $0}' | grep something > file
这是有效的,因为这些命令之间的数据流可以被认为是“文本”类型。
但是,在python中,对于那些未知函数,输入参数和返回结果基本上有各种类型的可能性。如果我想调用这些函数,我必须知道它的定义。例如>>> def str_in_asciiout_out(str):
return ord(str)
>>>
>>> str_in_asciiout_out("a")
97
>>> str_in_asciiout_out(100)
# oops, I have to, try… expect…
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
str_in_asciiout_out(100)
File "<pyshell#0>", line 2, in str_in_asciiout_out
return ord(str)
TypeError: ord() expected string of length 1, but int found
尝试......除了......是正确而恰当的编码方式。
但是如果我想将数百个str_in_asciiout_out()相似的函数组合在一起并将它们放入一个未知的序列中,我所关注的是序列在短时间内传递的最佳结果。
例如,仅举例 假设我定义了1000个函数,每个函数可能需要运行一天才能通过给定的输入获得输出,我随机选择了200个函数到一个链中,并且 str_in_asciiout_out(100) 在运气不好的最后一个位置,我可能会有一个哎呀,直到浪费了199个小时。
这就是为什么我想知道函数是否能在浪费时间之前显示它的能力。
上面的代码是我所知道的一个丑陋的解决方案,所以我粘贴这个想法,看看是否有更好的解决方案来解决我的问题。
答案 0 :(得分:1)
我最近在Python generators上看到了一个幻灯片演示文稿,它通过生成器函数可以执行许多简洁的操作,允许您像管道和过滤器系统一样使用它们。它们也被“懒惰地”评估,所以当你处理一个很长的列表时,它只会处理第一个列表所需的部分,以便为你提供生成的生成器的第一个输出。
在这看起来你有点想把自己的静态类型变成Python。虽然存在静态类型的情况,但我不确定尝试以这种方式在应用程序级别将其强制转换为动态语言是一个好主意。您可以通过在小输入上测试代码来改进您想要阻止的事情
最后,如果您尝试使用有关其返回类型的元数据来注释函数,那么最好为函数使用decorator。例如,如果您对使用类型感到不满意,可以使用类似example decorator from the Decorators PEP的内容:
def attrs(**kwds):
def decorate(f):
for k in kwds:
setattr(f, k, kwds[k])
return f
return decorate
@attrs(argument_types=(int, int,),
returns=int)
def add(a, b):
return a + b
然后,您只需访问f_inspect
的{{1}}和add.argument_types
成员变量,而不是使用add.returns
参数调用该函数。