phi是一个使用python进行流畅的函数式编程的库,它包含一个dsl+工具来创建与之集成的库。

phi的Python项目详细描述


#phi
python函数式编程的phi库,旨在尽可能地消除python函数式编程体验中的痛苦。

像这样,从phi.api导入的python
````python
import*
````
,但也可以从"phi"模块导入所需的内容。


你可以写一些东西,比如

`` python
f=(p*6)/(p+2)lambda x:(x*6)/(x+2)


断言f(2)==3(2*6)/(2+2)==12/4==3
````


``的表达式相当于

`` python
f=lambda x:(x*6)/(x+2)
````


35/>
访问某个实体的字段时,可以使用'rec'(用于记录)对象调用它上面的字段
``python
from collections import namedtuple
point=namedtuple('point',['x','y'])


assert f(point(3,4))==7 point.x+point.y==3+4==7
````
``方法调用
"+s.lower()

assert f("hello")="hello,hello";"hello".upper()+","+"hello".lower()="hello"+","+"hello"="hello,hello"
`````
这里不需要参数,但通常情况下,
``python
f=obj。一些方法(arg1,arg2,…);lambda obj:obj。一些方法(arg1,arg2,…)
```````````python
````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````+7>;>;math.sqrt从左到右执行

assert f(2)==3 math.sqrt(2+7)==math.sqrt(9)==3
`````
这是首选,因为它更具可读性,但您可以使用`<;<;`就像函数组合的数学定义一样,如果需要做很长的一段时间,p+7从右向左执行python
````

或者复杂的构图,可以使用"seq"(表示"sequence"),而不是多个链式的">">

``python
f=seq(
str,
p+"00",
int,
math.sqrt


assert f(1)==10 sqrt(int("1"+"00"))==sqrt(100)==10
`````
#"1"+"00"="100"
int,<100
math.sqrt<35; sqrt(100)==10

``


`
<

``python
f=list(p+1,p*10)lambda x:[x+1,x*10]


assert f(3)==[4,30][3+1,3*10]=[4,30]
```
相同的逻辑适用于"tuple"和"set"。使用'dict'时,必须使用关键字参数

`` python
f=dict(x=p+1,y=p*10)λx:[x+1,x*10]


d=f(3)


assert d={'x':4,'y':30}{'x':3+1,'y':3*10}={'x':4,"y":30}
assert d.x==4通过字段访问作为d.x访问d['x']####状态:读写
在内部,所有这些表达式都是以这样的方式实现的:它们不仅传递计算值,而且以函数方式在它们之间传递**状态**字典。通过读取和写入这个状态字典,"read"和"write"组合词可以帮助您"保存"中间计算的状态,以便以后读取它们

``python
assert[70,30]==pipe(
3,
write(s=p*10),p+5,<30+5==35
list(
p*2 35*2==70

read('s')s==30


``````
如果需要在列表中执行许多读取操作-通常用于输出-可以使用"readlist"代替"python"
"assert[2,4,22]==管道(
1,
写入(a=p+1),#a=1+1==2
写入(b=p*2),b=2*2==4
p*5,4*5==20
read list('a',b',p+2)[a,b,20+2]=[2,4,22]

`````
`readlist`将字符串元素解释为'read',因此前一个元素被转换为
``python
`list(read('a'),读('b'),p+2)
```

upper=false):
如果upper:
word=word.upper()

return[word]*次
````
使用"then"组合符,该组合符接受一个函数加上其`*args`+`**kwargs`
``python
f=p[:-1]>;然后(重复单词,3)
g=p[:-1]>;然后(repeat_word,3,upper=true)


assert f("ward")==["draw","draw","draw"]
assert g("ward")==["draw","draw","draw"]
`````
,并假设函数的*第一*参数将最后应用,例如,"word"在"repeat_word"的情况下。如果需要最后应用*2nd*参数,请使用'then2',依此类推。一般来说,可以使用"thenat(n,f,*args,**kwargs)",其中"n"是将最后应用的参数的位置。示例
``python
16][2**2,4**2]==[4,16]
````
请注意,"p"已经有了"map"和"filter"方法,因此您可以更轻松地编写前面的方法,如
``python
f=p.filter(p%2==0)>;p.map(p**2)>;list lambda x:map(lambda z:z**2,filter(lambda z:z%2==0,x))

assert f([1,2,3,4,5])==[4,16]35;[2**2,4**2]==[4,
````


`````````python
f=val(42)lambda x:42

assert f("whatever")==42
``````

`````````
`````````
```````````
`````````````````````````如果需要创建具有给定值的常量函数,请使用``````

assert f断言f("whatever")==f=42<42=42
`==42<如果还有更多,文档上的组合词。"p"对象还提供了一些有用的组合方法,如"not"、"first"、"last"plus**几乎所有**python内置函数作为方法:

`` python
f=obj.split(''')>;p.map(len)>;sum>;>;if((p<;15).not(),"太好了!收到{0}封信!".format).else("太短,至少需要15个字母")

assert f("short frase")="太短,至少需要15个字母"
assert f("一些较长的frase")="太好了!收到15封信!"
```

任何元素expression是dsl的一个元素。`所有的组合词都属于expression类。arity 1的任何可调用性都是dsl的一个元素。
3。容器类型"list"、"tuple"、"set"和"dict"是dsl的元素。它们被翻译成对应的"list"、"tuple"、"set"和"dict",它们的内部元素被转发。任何不符合前面任何规则的"x"值也是dsl的一个元素,并被转换为"val(x)"。


[10**2,3,4]=[100,3,3,4]=[100,3,3,4]
`````
可以重写为
````python
f=p**2>;[p,3,4]


assert f(10)=[100,3,4]=[10**2,3,3,4]==[100,3,3,4]=[100,3,4]=[100,3,3,4]=[100,3,3,4]=[100,3,3,3,4]==[100,3,3,3,3,4]>````````````>br/>这里将3和4的值)`多亏了*4*规则,`[…]`由于*3rd*规则被转换为`list(…)`。由于dsl无处不在,您可以在任何核心函数中使用它,因此可以使用"pipe"重写前面的dsl,如
``python
assert[100,3,4]==pipe(
10,
p**2,10**2==100
[p,3,4]\[100,3,4]

````

!,42,obj.upper())元组(p+"!!,val(42),obj.upper())

assert f("一些元组")=("一些元组!!42,"一些元组")
`````
`````python
f=f([p+n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n,总和([10,11,12,13,14])]==[5,(50+0+1+2+3+4)]==[5,60]
`````

因此,您也可以[流利地](https://en.wikipedia.org/wiki/fluent_interface)链接方法,而不是使用`>;`运算符。例如

`` python
f=dict(
x=2*p,
y=p+1
).元组(
rec.x+rec.y,
rec.y/rec.x


assert f(1)=(4,1)(x+y,y/x)=(2+2,2/2)=(4,1)
```
这个更复杂的前一个示例
``python
f=obj.split('')>;p.map(len)>;sum>;>;if((p<;15).not(),"太好了!收到{0}封信!".format).else("太短,至少需要15个字母")

assert f("short frase")="太短,至少需要15个字母"
assert f("一些较长的frase")="太好了!收到15封信!"
```
可以重写为
``python
f=(
obj.split('')
.map(len)
.sum()
.if((p<;15).not(),
"太好了!收到{0}封信!".format
).else(
"太短,至少需要15个字母"




assert f("short frase")="太短,至少需要15个字母"
assert f("一些较长的frase")="太好了!收到15封信!"
```

您可以创建一个自定义类,该类继承自'builder'或'pythonbuilder`
``python
from phi import pythonbuilder


class mybuilder(pythonbuilder):
pass

```
,并使用'register'类在其中注册您的函数方法

`` python
def remove_longer_than(some_list,n):
返回[elem from elem in some_list if len(elem)<;=n]


mybuilder.register(remove_longer_than,"my.lib。")
````
甚至更好地使用"register"作为装饰符
``python
@mybuilder.register("my.lib.")
def remove比(some_list,n)长:
如果len(elem)<;=n,则返回[elem for elem in some_list/>现在该类上存在"mybuilder.remove\u longer"方法。然后,您可以这样使用它:obj.split(''')>;m.remove_longer_than(6)

assert f("some are longggggggggg")=["some","are"]
```
正如您所看到的,参数"n=6"部分应用于"remove_longer_than",一个等待的表达式返回"some_list"参数。在内部,"registar*"方法族使用"then*"方法族。

这是一种将整个模块集成到phi的dsl的简单方法。请参见"patchat"。

一帮有用的帮手,做些普通的事情。` phi的全局"p"对象是此类的一个实例。[与phi一起提供]
*[tensorbuilder](https://github.com/cgarciae/tensorbuilder):tensorflow库使您能够通过利用phi dsl帮助定义它们的结构,轻松创建复杂的深层神经网络。
*numpybuilder:即将投入使用!

文档
查看[完整文档](https://cgarciae.github.io/phi/)。

更多示例
全局"phi.p"对象公开大部分api,最好直接导入。DSL做的最简单的事情是函数组合:

`` python
来自phi.api import*

def mul3(x):return x*3

1.0,input 1
add1,#1+1==2
mul3 2*3==6





35;1+1==2
p*3 2*3==6


assert x==6
`````



p*3 1*3==3
]





assert x==2
assert y==3
`` ` `




assertx==2
asserty==3
` ` ` ` ` ` `(x(x)(x+3)/(x+3)/(x+1)`
` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` P+3)/(P+1),(1)+3)/(1+1)==4/2==2
[
p+1<2+1==3

>p*3<2<2<2<2<2









assert x==3
assert y==6
` ` `==6
` ` ` ` `







1.0,#输入1
(p+3)/(p+1),(1+3)/(1+1)==4/2==2
dict(
x=p+1<2+1==3

y=p*3<2*3==6




assert result.x==3assert result.y==6

通过"y"。

`` python
API导入*


>result=pipe(
>1.0,输入1
(p+3)/(p+3)/(p+1),(1+3)/(1+1)==4/2==2
dict(
>x=p+1,2+1==3

>y=p*3,2*3==6

>rec.x/rec.x/rec.y/rec.y/rec.y;3/6==0.5



断言结果==0.5
```

将来自`(p+3)/(p+1)`计算的值保存为's',并将其加载到分支的末尾

``python
from phi.api import*

[result,s]=管道(
1.0,输入1
写入(s=(p+3)/(p+1)),s=4/2==2
dict(
x=p+1 2+1==3

y=p*3 2*3==6

[
rec.x/rec.y 3/6==0.5

读('s’)s==2
]


assert s==2
````

#s=4/2==2
听写(
x=p+1 2+1==3

y=p*3 2*3==6
),
[
rec.x/rec.y 3/6==0.5

read('s')+3 2+3==5
]



assert s==5
`````


>使用"read"和"write"字段访问lambda样式,因为从phi.api导入的python
[result,s]=管道(
1.0,#输入1
(p+3)/(p+1),4/2==2
写入s,s=2
指令(
x=p+1 2+1==3

y=p*3 2*3==6

[
记录x/rec.y=3/6==0.5

read.s+3 2+3==5
]



assert s==5
`````


#输入1
(p+3)/(p+1),写入s,4/2==2,另存为s,
dict(
x=p+1+1==3

y=p*3=p*2*3==6


[
(p+3/6==0.5
(p+3/6==0.5

(p+3)
,读取s+3 2+3==5

val(9)+1输入9加1,得到10
]



assert result==0.5
assert s==5
assert val==10
````

VAL]=管道(
>1.0,输入1
(p+3)/(p+1),写入,4/2==2,另存为"s"
dict(
>x=p+1,2+1==3

y=p*3,2*3==6


[
rec.x/rec.y,3/6==0.5
rec.x/rec.y/rec.y,3/6==0.5=0.5/>,
读取.s+3 2+3==5

if(rec.y>;7,
val(9)+1输入9和加法1,得到10
)否则(
"对不起,请稍后再来。"

]


assert result==0.5
assert s==5
assert val="对不起,请稍后再来。"
```

使用"seq"我们可以获得独立函数,然后使用它从phi.api import中获取与以前相同的值

``python


(p+3)/(p+1),write.s,4/2==2,另存为's'
dict(
x=p+1 2+1==3

y=p*3 2*3==6

[
rec.x/rec.y 3/6==0.5

读取.s+3+3==5

如果(rec.y>;7,
val(9)+1输入9加1,则返回10
)。否则(
"抱歉,请稍后再来。"

]




[result,s,val]=f(1.0)


>assert result==0.5
assert s==5
assert val=="对不起,请稍后再来。"
```
` `
` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
obj.split(""),[1,2,3]
p.sum()/p.len()和([1,2,3])/len([1,2,3])=6/3==2



assert 2==avg g g g u word长度
`
`

*

assert false==管道(
[1,2,3,4],p
.过滤器(p%2!=0)[1,3],保持赔率
。包含[1,3]==false
`````

``python
``python
s keys=['a','b','c']
.map(ord),[ord('a'),ord('b'),ord('c')]==[97,98,99]
lambda it:zip(ref.keys,it),[('a',97),('b',98),('c',99)
dict{'a':97,'b':98,"C":99}


``````



<<













<35<<35<35<35<35<

p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p g git g git g gi
*文档覆盖率:100%。如果文档不清楚,请创建一个问题,这是此库的高优先级。
*里程碑:在社区反馈后达到1.0.0。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
servlets Java EE+GlassFish:如果用户在其他地方登录,则强制用户注销   java在不更改源代码的情况下添加钩子   安卓 Java TextView Onclick()返回表达式错误   java Excel文件未使用Apache存储内部内存   java getRowCount()和getSelectedColumn()不起作用   无法在java中生成视图绑定。util。Android Gradle插件2.1的NoTouchElementException   Java中的类型转换运算符百分比计算为零   主java中的调用方法   java在Javasound中播放多个示例   java如何知道webDriver成功打开URL   java jmock,每次调用时返回新对象   eclipse使用Java在Selenium WebDriver中生成可执行文件   macos捆绑Java OS X应用程序默认为MacRoman编码   java我应该把我的休息网关变成一个图书馆吗?   java Eclipse插件:查找包含子字符串的行号无效   Java IOException:在Linux上发送UDP数据包时没有可用的缓冲区空间   java无法解析jaxbxjc2中的名称“xjc:globalJavaType”。2.52.罐子   java是否有HibernateAPI来检查是否创建了数据库?