关于python:λ-演算在-PY扔掉游标卡尺并用-PY-拼接代码

<!– 【λ 演算在 PY】扔掉游标卡尺并用 PY 拼接代码 –>

PY 里执行字符串用 exec()eval()

  • 前者能够执行个别的代码,但不会有返回,你就当执行一个 .PY 的脚本。
  • 后者能够有返回,但只能是一条语句。嗯,一条语句。🙃

这个挺不错的: https://github.com/pyecharts/pyecharts 特地是图标。

'我永远喜爱海绵宝宝'

它有个示例。我跟着这里和这里略微改了一下,成了这样:

from pyecharts.charts import Bar
from pyecharts import options as opts

(
    Bar(init_opts=opts.InitOpts(width="680px",height="390px",page_title="HAHAHAHA"))
    .add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
    .add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
    .add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
    .set_global_opts(title_opts=opts.TitleOpts(title="某商场销售状况"))
).render("shangjias.html")

而后我有了一个想法:我想主动生成一个两头局部随机的能够指定商家数目的这段代码。

好,一边查一边干!(一边查是因为我不会 PY ,也正因而才有了这份……笔记?)

辨析 execeval

其实 Bash 也有这俩玩意。不过,我只会玩前者,用来模拟一个 先实现本次调用的函数再开始下次调用 的成果,从而在 Bash 上实现 函数式 的尾递归。看 PY 里也有,一开始还有点小冲动,但 PY 的过程逻辑跟 Bash 必定不一样,我就权且先放下这个小冲动。

当初的大业是,玩 PY 不必游标卡尺,和,用 PY 玩动静代码,这两项,别的《稍》后再钻研。。

其实辨析很简略,在 PY 里:

  • 前者能够执行个别的代码,但不会有返回,你就当执行一个 .PY 的脚本,无返回。
  • 后者能够有返回,但只能是一条语句。嗯,一条语句。🙃

Note

其实这个设计很正当。
不然,就会像 Powershell 那样,一个函数居然能够有多个返回了,那就太吓人了。

《一样简略的示例》:

你先复制上面的代码进入你的 PY 而后敲一下回车,你就晓得它意味着什么了:

'{}\n{}'.format(1,2)

晓得下面的意味着什么就晓得上面的意味着什么了:

'{}\n{}'.format("'yaya{}rara'",".format(2)")

就晓得上面的代码意味着什么了(返回后果上这两个一样但倡议用前者即 格局数据别离定义 准则):

'({}\n{})'.format("'yaya{}rara'",".format(2)")
'{}\n{}'.format("('yaya{}rara'",".format(2))")

行了,睁大眼睛,咱们要开始了!

咱们先看看 execeval 解析上面那坨字符串时候的成果:

exec('({}\n{})'.format("'yaya{}rara'",".format(2)")) # 没返回也没打印也没报错(代码没打印也没错)
eval('({}\n{})'.format("'yaya{}rara'",".format(2)")) # 返回: 'yaya2rara'

再看看这个:

exec('{}\n{}'.format("'yaya{}rara'",".format(2)")) # 报错
eval('{}\n{}'.format("'yaya{}rara'",".format(2)")) # 报错

报错一样,因为 PY 不反对比拟自在的格式化,除非在括号里🙃。(这也是我的可乘之机,当然我不光用圆括号 () ,次要还是方括号 [] 和拉拔哒 lambda 。)

堆数

这里先留下一个小纳闷:个别 Java 或 Scala 都能够写全类名来防止 import ,但 PY 就是不行。当然,也可能是还有别的我不晓得的方法。但不管怎样,既然如此,我就给引入的随机从新起个名字好了,就叫 随机 好了!

import random as 随机

Note

可能我须要特地明着强调一下:上面的代码执行的前提是曾经执行过了下面的这个 import
其实我很不喜爱这种设计:我感觉一行代码自带了所有局部会比拟好,而不是它只是必要工作的一部分。如果只是一部分,你让孩子们上哪儿找别的局部去呢?孩子们就要伤心了呀🤢🤢。。。。

咱们先搞一个随机列表:

[随机.randint(222,333) for i in range(12)]

能够多执行几次,看看样子。为什么让你看看它的样子?因为你马上就再也见不到它了。。。。

在见不到它之前,先补充一下对于 lambda 的知识点。不难,执行上面代码比比看就好:

1+2 # 返回: 3
(lambda x,y: x+y)(1,2) # 返回: 3

1+1 # 返回: 2
(lambda x: x+x)(1) # 返回: 2

[e+7 for e in range(4)] # 返回: [7, 8, 9, 10]
(lambda x: [e+7 for e in range(x)])(4) # 返回: [7, 8, 9, 10]

['ahaha {} jijijijijiji'.format(e) for e in range(4)] # 返回你本人试。
(lambda x: ['ahaha {} jijijijijiji'.format(e) for e in range(x)])(4) # 返回你本人试(反正跟下面一样)。

这么看来,可能会有人说了, “这个 lambda 不就是多此一举嘛” ,这你就不晓得了,如果只让你写一行代码,这就不能赋值了,但又要你把某个随机数用两次,你怎么办呢?

先不说这个,反正前面马上会遇到。🙃

而且须要用到 lambda 的中央曾经遇到了,那就是咱们想要提取 写定的数值变量

(lambda cnt: [随机.randint(222,333) for i in range(cnt)])(7)

这样就是定义一个函数并立即调用,返回后果是有 7 个随机数的列表,随机数是 222333 之间的 int 数(即整数)。

另外, lambda 函数定义自身就相当于是一个 写定的数值 ,只不过类型不是 int 也不是个别的别的什么类型。总之,它会像一个数值一样被返回。从而,能够有上面的定义:

lambda cnt: 
    (lambda low,high: 
        ( [随机.randint(low,high) for i in range(cnt)] )
    )

调用:

(lambda cnt: 
    (lambda low,high: 
        ( [随机.randint(low,high) for i in range(cnt)] )
    )
) (7) (222,333)

这里其实产生了两次调用,第一次调用的参数列表是 (7) ,返回了一个内容是这样子的值: lambda low,high: ( [随机.randint(low,high) for i in range(7)] ) 而后它前面又有参数列表 (222,333) ,就又被调用了一次,这次调用就相当于执行 [随机.randint(222,333) for i in range(7)] 了。(事实上,执行 lambda 啥啥: 啥啥 命令返回后果就是一个内容lambda 啥啥: 啥啥确定值 。)

Note

其实,把函数作为值传来传去这种事,用 Lisp 系列的语言写起来会十分直观。只不过本文是在玩 PY ,所以就不打算好好介绍 Lisp 的 S 表达式 的那种代码了,能够本人查一查 Scheme 的语法以及 lambda 的写法。

下面的调用后果就是 一个有 7 个随机数的列表,随机数是 222333 之间的 int 数(即整数)

好了,我当初想要搞好几个这样的列表!

那么好,假如咱们有这样一个列表

[
    ('商家1',(200,300)),
    ('商家2',(50,600)),
    ('商家3',(80,100))
]

接下来只须要 ……

这不够!我还想要每个的参数还都不一样!我不想本人定,就想用随机数!

好,那就学生成一个能够指定数目的这样的列表。

咱们须要对 随机.randint(x,y) 这个函数传入随机的参数,并且要确保第一个小于第二个。

我的思路是,确定第一个随机值,第二个就随机加一个增量。

思路有了,开干。

首先,弄一个 '商家X' 前面那样的一个元组进去,随机地:

(随机.randint(40,300), 随机.randint(40,300) + 随机.randint(10,600))

等等!完蛋去吧!这样齐全有可能会让第二个数更小!因为两个 随机.randint(40,300) 齐全可能不是一样的值!!!!

怎么办?我当初曾经不容许我本人把值赋值给变量了!怎么办!

lambda :别放心,小伙子!想一想这个美好的构造: (lambda a (a a)) (这个是 Scheme 里的写法,等价的 Python 写法是这样: (lambda a: a(a)) 。怎么样?是不是 Scheme 比拟牛逼?😶)(另外这个构造来自
Y 组合子 。)
其实这样举例更简略: (lambda x: x+x) 这不就是用了两次!同一个数!!!!不信能够验证: (lambda x: (x,x+x))(随机.randint(40,300))

总之,当初咱们有主见搞定下面的须要了:

(lambda rndlow, add: (rndlow , rndlow + add) ) (随机.randint(40,300), 随机.randint(10,600) )

这里就不把原本的第二个参数打印进去了,想看看的话无非是能够这样: (lambda rndlow, add: (rndlow , rndlow + add , add)) (随机.randint(40,300), 随机.randint(10,600) ) ,其中第二个数必定就是第一个第三个的和,每次必定都是。

当初,一个这玩意(就是一个二值元组),咱们搞进去了。当初,咱们须要一个列表,列表里,要有好几个这玩意。

指定长度的列表咋弄?看:

[elem*2 for elem in range(12)]
['heihei {} miaomiao'.format(elem) for elem in range(12)]

[随机.randint(40,300) for elem in range(12)] # 返回 12 个 40 ~ 300 的随机数
[(随机.randint(40,300), 随机.randint(10,600)) for elem in range(12)] # 返回 12 个的二值元组,第一个值是 40 ~ 300 的随机数,第二个值是 10 ~ 600 的随机数(两个值的数值当然并没什么关系在逻辑上它们是独立着随机的)

后两行其实最初没有用到 elem ,被传递上来的 信息 只有 elem 一共有几个 这一点。

其实这个 [新汇合单个元素模式 for 根据元素 in 根据元素起源汇合] 的写法,一开始我非常不解,看不懂它各个局部为什么是这样的含意,因为我总往 for 循环的模式上想。起初理解 Erlang ,看到了列表结构器是这样写的: [新汇合单个元素模式 || 根据元素 <- 根据元素起源汇合] 我就一下就明确 PY 这种设计是哪儿来的想法了。

行了,我想要一个二值元组,但第二个肯定比第一个大:

[ (lambda rndlow,add: (rndlow,rndlow+add)) (随机.randint(40,300), 随机.randint(10,600) ) for will_not_use in range(13) ]

来, 13 个。

格式化一下吧,曾经很长了。

[   (lambda rndlow,add: 
            (rndlow,rndlow+add)
    ) (随机.randint(40,300), 随机.randint(10,600) ) 
    for will_not_use in range(13) 
]

发现没?尽管咱们是在玩 PY 然而这里竟然是 格式化自在 的!!!!

(这只是借用 PY 的个性罢了:括号里间断空白符会被视为一个 —— 当然,这是我的集体总结,不代表 PY 那个委员会的态度。。。)

Note

这里我的格式化准则是这样的:

  • 值个数确定的列表或元组,前后括号高低对齐、内容加一次缩进一项一行。
  • 列表生成器,前方括号后若干空格后跟第一项,而后 for 表达式另起一行并一次缩进。
  • lambda 表达式的话,被调用当然要包上圆括号了就。定义头能够尽量紧跟着前圆括号,也能够换行,换行的话,绝对于前圆括号所在层级,再往后缩进两层,这个前括号对应的后括号也同样如此缩进并且该当只在这时候才另起一行,除非你能让它高低对齐;返回值局部的定义,能够另起一行,如果另起一行,就要绝对 lambda 多往后缩进一次。
    除了包裹 lambda 定义的小括号在内容另起一行的时候以外,所有括号,该当想方法确保要么横着是一对要么竖着是一对。如果新增新的格式化规定,也是在确保这一条的前提下进行的,或者就是为了更好确保这一条而进行。
  • lambda 定义被调用的话,为了难看,最好确保包裹定义的后括号和参数列表之间有所距离;但为了不便你调试,所以最好别距离到下一行,只用空格距离就好拉。
  • 参数列表内容如果独自换行,向后一次缩进,尾括号能够跟后面的逗号竖着对齐而不是跟对应的头括号。(这应该是惟一的容许高低一对括号不对其的中央。遵循这个准则,也能够做到:一看到不对齐的括号,就晓得它后面是参数列表。)

当初也能够轻易让后果跟下面那列表更像:

[   (
        '商家{}'.format(i+1) ,
        (lambda rndlow,add: (rndlow,rndlow+add))(
                随机.randint(40,300) ,
                随机.randint(10,600) )
    )
    for i in range(13)
]

格局换后看就很容易看了:只是 for 后面的内容进入了一对圆括号(这对是起到建设元组的作用),而后在
[0] 地位加上了一个字符串值。当然这个值这里就用到了来自 range(13) 的元素 i 的内容。

那我想本人指定这个数量 13 呢:

(lambda cnt: 
    [   (
            '商家{}'.format(i+1) ,
            (lambda rndlow,add: (rndlow,rndlow+add))(
                    随机.randint(40,300) ,
                    随机.randint(10,600) )
        )
        for i in range(cnt)
    ]
) (13)

行了,当初它返回的是个列表,列表的一个元素的内容可能是这样: ('商家3', (240, 713))

当初咱们想造成这样一个列表,它的每个元素都是相似这样 ('商家3', [420, 285, 495, 539, 269, 296, 293]) 的:

[   (
        sj[0], 
        (lambda cnt: 
            lambda low,high: 
                [随机.randint(low,high) for i in range(cnt)]
        )(7)(sj[1][0],sj[1][1]) 
    )
    
    for sj in 
        (lambda cnt: 
            [   (
                    '商家{}'.format(i+1) ,
                    (lambda rndlow,add: (rndlow,rndlow+add))(
                            随机.randint(40,300) ,
                            随机.randint(10,600) )
                )
                for i in range(cnt)
            ]
        )(13)
] 

其中:

  • 第一个 [ 前面紧跟着新生列表的每个元素的计算逻辑,这个计算的变量根据就是 forin 之间的那串玩意,这个玩意(在这里就是叫 sj 的那个玩意)的内容来自于前面的汇合的每一项,当然,这个汇合是根据一个输出数值能力生成的。
  • 而对于在新生列表的每元素的逻辑,首先,它是个元组,第一项是商家号,而它在此刚好能依据 sj[0] 获得;前面须要有一个 7 长度的随机数列表,生成它的 lambda 定义后面曾经定义过了,须要的参数则能够依据 sj[1] 这个元组取到,具体就是别离取 sj[1][0]sj[1][1] ,填写在传入参数须要写在的那个正确地位,而后函数就能依据参数的指定生成依据参数与函数定义而造成的随机数列表了。
  • 这样一来,只有 sj 始终能被确定是什么内容,而且这个内容的结构式以及构造各个地位的数据的类型也都是合乎要求的,那么最终后果就能进去了;好巧不巧,这两点咱们的数据源都能达到。🙃🙃🙃

如此一来,相似于 ('商家3', [420, 285, 495, 539, 269, 296, 293]) 这样的一堆数据咱们就可能生成了。

它有啥用?它的两项别离一填不就拼出代码来了吗?

[   '    .add_yaxis("{}",{})\n'.format(sj_msg[0],sj_msg[1])

    for sj_msg in 
    [   (
            sj[0], 
            (lambda cnt: 
                lambda low,high: 
                    [随机.randint(low,high) for i in range(cnt)]
            )(7)(sj[1][0],sj[1][1]) 
        )
        
        for sj in 
            (lambda cnt: 
                [   (
                        '商家{}'.format(i+1) ,
                        (lambda rndlow,add: (rndlow,rndlow+add))(
                                随机.randint(40,300) ,
                                随机.randint(10,600) )
                    )
                    for i in range(cnt)
                ]
            )(13)
    ] 
]

当然,这还不够,咱们须要的是一个字符串。

上面又要引入一个货色: reduce

这里我想多说一句:其实也不必引入,单纯用 lambda 我能做到手动实现一个差不多的货色!看:

## 定义
(lambda selfff: selfff(selfff)) ( lambda selff: lambda op, list, res: res if (list == []) else (selff(selff))(op,list[1::],op(res,list[0])) ) 

## 定义并调用
(lambda selfff: selfff(selfff)) ( lambda selff: lambda op, list, res: res if (list == []) else (selff(selff))(op,list[1::],op(res,list[0])) ) (lambda x,y:x-y, [5,4,3,2,1], 6)
## 返回就像这个的后果一样:
6-5-4-3-2-1 # 返回: -9

## 定义并调用格式化一下
## 这是非通用的 Y 组合子 用来让匿名函数能够本人调用本人
(lambda selfff: selfff(selfff)) (
    lambda selff: 
        lambda op, list, res: 
            
            ## 这上面是退出逻辑
            res if (list == []) 
            else (selff(selff))(
                
                ## 这里是递归 上面是新的参数 下面是生成一个本人而后能力递归能力传新参数
                op,list[1::],op(res,list[0]) ) ) (
    
    ## 这个是这次定义在调用时候的参数列表: 传入逻辑是前减去后后果再减去后、列表是第二项、初始值是第三项。
    lambda x,y:x-y , 
    [5,4,3,2,1] , 
    6 )

下面的局部不须要把握,本人把最上面的参数轻易换一换执行看看后果就好。这部分,我只是想阐明一下聚合函数是能够只通过 lambda 定义的。。。

上面还是用引入的 reduce

引入的话,老常规,换个名儿。

from functools import reduce as 汇总

请留神!要有这个引入,而后能力执行上面的代码!!

先应用一下这个函数看看成果:

汇总 (
    lambda x,y:x+y ,
    [   '    .add_yaxis("{}",{})\n'.format(sj_msg[0],sj_msg[1])

        for sj_msg in 
        [   (
                sj[0], 
                (lambda cnt: 
                    lambda low,high: 
                        [随机.randint(low,high) for i in range(cnt)]
                )(7)(sj[1][0],sj[1][1]) 
            )
            
            for sj in 
                (lambda cnt: 
                    [   (
                            '商家{}'.format(i+1) ,
                            (lambda rndlow,add: (rndlow,rndlow+add))(
                                    随机.randint(40,300) ,
                                    随机.randint(10,600) )
                        )
                        for i in range(cnt)
                    ]
                )(13)
        ] 
    ] )

这里的返回值不会有本义,不过没事,紧接着会有成果更直观的预览。这里只须要确认是不是胜利返回一个加总好的字符串就行了。

更好的预览计划:

x = lambda : 汇总 (
    lambda x,y:x+y ,
    [   '    .add_yaxis("{}",{})\n'.format(sj_msg[0],sj_msg[1])

        for sj_msg in 
        [   (
                sj[0], 
                (lambda cnt: 
                    lambda low,high: 
                        [随机.randint(low,high) for i in range(cnt)]
                )(7)(sj[1][0],sj[1][1]) 
            )
            
            for sj in 
                (lambda cnt: 
                    [   (
                            '商家{}'.format(i+1) ,
                            (lambda rndlow,add: (rndlow,rndlow+add))(
                                    随机.randint(40,300) ,
                                    随机.randint(10,600) )
                        )
                        for i in range(cnt)
                    ]
                )(13)
        ] 
    ] )
print(x())
print(x())
print(x())

这里的 print(x()) 能够多执行几次。你会看到数在变,因为每次都是从新从头来一遍这个过程。

这里赋值给 x 只是为了不便上面的 print 函数。毕竟 Python 的 REPL 按上的话并不是逻辑意义上的一行都会进去,并不会像 Zsh 或者哪怕是 Bash 那样。

当初,赋值给 x 的最外层的 lambda 定义是无参的。要不要有一下呢?哎,这个商家数量我想在这管制!

那么就把外面的相应的形象挪到里面来。整个定义就变成了这样:

lambda cnt : 汇总 (
    lambda x,y:x+y ,
    [   '    .add_yaxis("{}",{})\n'.format(sj_msg[0],sj_msg[1])

        for sj_msg in 
        [   (
                sj[0], 
                (lambda cnt: 
                    lambda low,high: 
                        [随机.randint(low,high) for i in range(cnt)]
                )(7)(sj[1][0],sj[1][1]) 
            )
            
            for sj in 
                [   (
                        '商家{}'.format(i+1) ,
                        (lambda rndlow,add: (rndlow,rndlow+add))(
                                随机.randint(40,300) ,
                                随机.randint(10,600) )
                    )
                    for i in range(cnt)
                ]
        ] 
    ] )

调用:

(lambda cnt : 汇总 (
    lambda x,y:x+y ,
    [   '    .add_yaxis("{}",{})\n'.format(sj_msg[0],sj_msg[1])

        for sj_msg in 
        [   (
                sj[0], 
                (lambda cnt: 
                    lambda low,high: 
                        [随机.randint(low,high) for i in range(cnt)]
                )(7)(sj[1][0],sj[1][1]) 
            )
            
            for sj in 
                [   (
                        '商家{}'.format(i+1) ,
                        (lambda rndlow,add: (rndlow,rndlow+add))(
                                随机.randint(40,300) ,
                                随机.randint(10,600) )
                    )
                    for i in range(cnt)
                ]
        ] 
    ] )
) (4)

看看后果,没问题。

当初能够欢快游玩了:

x = lambda cnt : 汇总 (
    lambda x,y:x+y ,
    [   '    .add_yaxis("{}",{})\n'.format(sj_msg[0],sj_msg[1])

        for sj_msg in 
        [   (
                sj[0], 
                (lambda cnt: 
                    lambda low,high: 
                        [随机.randint(low,high) for i in range(cnt)]
                )(7)(sj[1][0],sj[1][1]) 
            )
            
            for sj in 
                [   (
                        '商家{}'.format(i+1) ,
                        (lambda rndlow,add: (rndlow,rndlow+add))(
                                随机.randint(40,300) ,
                                随机.randint(10,600) )
                    )
                    for i in range(cnt)
                ]
        ] 
    ] )
print(x(1))
print(x(2))
print(x(3))
print(x(0))

。。。不能是 0 ,因为 reduce 传入的列表不能为空(因为 reduce 个别的逻辑就是把第一个做初始值而后把剩下的列表和初始值还有计算规定都传入另一个能够定义初始值的聚合函数。)

刚好,试试我后面自制的那个:

x = lambda cnt : (lambda selfff: selfff(selfff)) (
    lambda selff: 
        lambda op, list, res: 
            
            res if (list == []) 
            else (selff(selff))(
                
                op,list[1::],op(res,list[0]) ) ) (
    lambda x,y:x+y ,
    [   '    .add_yaxis("{}",{})\n'.format(sj_msg[0],sj_msg[1])

        for sj_msg in 
        [   (
                sj[0], 
                (lambda cnt: 
                    lambda low,high: 
                        [随机.randint(low,high) for i in range(cnt)]
                )(7)(sj[1][0],sj[1][1]) 
            )
            
            for sj in 
                [   (
                        '商家{}'.format(i+1) ,
                        (lambda rndlow,add: (rndlow,rndlow+add))(
                                随机.randint(40,300) ,
                                随机.randint(10,600) )
                    )
                    for i in range(cnt)
                ]
        ] 
    ] , 
    '' )
print(x(1))
print(x(2))
print(x(3))
print(x(0))

如果是 0 返回就是空。为啥?你看我给定的那第三个参数不就是空字串嘛!!

🤣🤣🤣🤣(嘿嘿嘿嘿嘿嘿嘿嘿…………)

(不过这没啥大不了的,我只是没能实现封装好的 reduce 罢了。。。)

当初再改改,就能拼接残缺的代码了。我间接上后果:

xforexec = (
        lambda cnt : 
        """
from pyecharts.charts import Bar
from pyecharts import options as opts

(
    Bar(init_opts=opts.InitOpts(width="680px",height="390px",page_title="HAHAHAHA"))
    .add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
{}    .set_global_opts(title_opts=opts.TitleOpts(title="某商场销售状况"))
).render("shangjias.html")
        """.format(
            (lambda selfff: selfff(selfff)) (
            lambda selff: 
                lambda op, list, res: 
                    
                    res if (list == []) 
                    else (selff(selff))(
                        
                        op,list[1::],op(res,list[0]) ) ) (
            
            
            
            lambda x,y:x+y , 
            
            [   '    .add_yaxis("{}",{})\n'.format(sj_msg[0],sj_msg[1])

                for sj_msg in 
                [   (
                        sj[0], 
                        (lambda cnt: 
                            lambda low,high: 
                                [随机.randint(low,high) for i in range(cnt)]
                        )(7)(sj[1][0],sj[1][1]) 
                    )
                    
                    for sj in 
                        [   (
                                '商家{}'.format(i+1) ,
                                (lambda rndlow,add: (rndlow,rndlow+add))(
                                        随机.randint(40,300) ,
                                        随机.randint(10,600) )
                            )
                            for i in range(cnt)
                        ]
                ] 
            ] , 
            
            '' ) )
        )
exec(xforexec(3))

为什么不必 eval ?因为这个货色最初没有返回,而是副作用生成一个文件。

其实这里去掉字符串里的俩 import 的话,就也能用 eval 了,不过它毕竟不是函数而是副作用命令汇合(虽说失效的只有一条)。

想要看看这个文件的话,能够退出 Python REPL 而后这样:

python -m http.server 2341

而后拜访 节点IP:2341/shangjias.html 就能看到后果了。

这是个 HTTP 代理,个别用于调试。生产中倡议应用 Httpd 或者 Nginx 来做这个事。

备忘

本文一共有两个 import

import random as 随机
from functools import reduce as 汇总

分享注明起源: https://segmentfault.com/a/1190000040317072

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理