V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  O5oz6z3  ›  全部回复第 4 页 / 共 5 页
回复总数  100
1  2  3  4  5  
@1018ji #15 是我说复杂了,简单来说的话就是:“把函数定义放在字符串里,定义的时候就可以省略关键字 lambda 、def 和函数名。这样的语法糖设计大家觉得实用吗?”(虽然这样的设计实现起来很简单,但是没有了语法高亮和可读性)
@ztcaoll222 #11 不懂 lisp,所以不知道指的是哪一点像……

@ClericPy #12 比 AST 还抽象那是不敢当……不过我的确也说不明白,大概是三个问题的混合:
1. lambda 前缀写起来有点长,有没有什么库提供更简便的生成函数表达式的方法。
2. 有关 python 的 DSL 库,有没有什么值得推荐的库。
3. 针对第一点,想到一个“简单”的解决思路,这个思路如何、是不是已经有人实现过了。

不过我的“解决思路”也描述得很抽象,所以讨论也无从谈起……

@KAAAsS #13 你说的代码高亮确实是个问题。强求单行则是为了能在表达式里塞下函数定义,比方说 map() 需要的映射函数,有了匿名函数就可以直接在定义在表达式里`map((lambda a: a+2), list)`,如果用换行的方式就不太方便了。
@hsfzxjy #8 谢谢!
说实话,这个帖子的想法正是来自于实现管道语法糖,整件事颇有点函数式尾递归的味道,其中遇到了需要经常定义 lambda 的问题,然后就想到了这个伪语法糖,想抛砖引玉一下。

先不说我水平有限无法完整实现 DSL,要我用现成的语法组成 DSL 就变成 ORM 了,所以偷懒直接沿用 python 自己的语法。

@LeeReamond #9 确实!所以想参考大家意见……
@hsfzxjy #1
确实大开眼界,语法很自由可读,设计很完善,完成度非常高,大受震撼……不过话说回来,我的目标是缩写 lambda,你的目标是强化 lambda,方向不一样。
@gstqc @lichdkimba @efaun @raaaaaar
不好意思,我写得太抽象了,补充了一些描述在附言里。

@raaaaaar #5
这不是你的问题,是我的问题,python 没有这些语法糖。只是我自己想到了一个很简单就可以实现的伪语法糖,想问问大家意见。
2021-08-02 12:03:53 +08:00
回复了 O5oz6z3 创建的主题 Python 想请教几个有关 py3 的 exec、字节码和代码对象的问题
@abersheeran #12 明白了,docker yyds !说到底在脚本层面实现简单的沙箱只是我一个待验证的突发奇想而已,根本不能和正经沙箱相提并论,更别说对付逃逸沙箱水平的黑客……
2021-08-02 11:05:12 +08:00
回复了 O5oz6z3 创建的主题 Python 想请教几个有关 py3 的 exec、字节码和代码对象的问题
@no1xsyzy #10
如果我没又理解错的话,你说的意外访问不可用资源指的是“文件系统的权限问题”?这确实是可能会在现实发生的情况,不过我不打算解决这类复杂的问题,而且访问权限不够似乎也不是沙箱的责任。至于 ffi 接口我就不懂了……

eval_literal 我也了解过,不过那就只是数据不是代码了,所以没考虑。

原来重写解释器是指元解释器,似乎可行,不过这既不简单也不粗暴,工作量令我望而生畏,所有也不考虑了。

你这么一说确实是黑名单策略。至于白名单应该不太可行,一是限制了语法的自由度,二是我也无法穷举出所有安全的属性名。
2021-08-02 07:30:28 +08:00
回复了 O5oz6z3 创建的主题 Python 想请教几个有关 py3 的 exec、字节码和代码对象的问题
@no1xsyzy #8
你说的沙箱最大的问题:“沙箱权限的细粒度控制”可以很复杂,对我反而不重要,因为我只是想简单粗暴地做一个最小可用沙箱的概念验证 /POC,具体来说就是只能使用基本语法,不能使用任何 builtins 内置函数或 import 功能。

长见识了,原来还有 deno 这种沙箱。

至于用 ast 重新写解释器,先不说我没那个水平,原来 ast 还能这么用?我还以为 ast 只能静态修改抽象语法树,不能用来解释运行,而且也无法识别出表达式的最终结果。

不过这启发了我想到另一种实现沙箱的大致思路:针对 builtins 的泄露问题,使用 ast 或者 tokenize 识别第三方脚本中关键的内省属性,比如 __subclasses__、__globals__,然后要么抛错要么替换要么禁用就能解决。缺点是只能针对这种已知的访问 builtins 的方法,对未知的就没有办法预防了。
比如说 exception 附带的堆栈也许有可能会泄露 builtins,就没有办法了。
2021-08-01 20:22:43 +08:00
回复了 O5oz6z3 创建的主题 Python 想请教几个有关 py3 的 exec、字节码和代码对象的问题
@hsfzxjy #5
“可以通过内置对象访问到原先的 builtins”,回过头来发现,exec 本质上就是在当前解释器环境解释执行代码,复用了当前环境的内置对象,那么能够通过自省访问到原先的 builtins 也就不奇怪了。看来想简单地用 exec 来实现沙盒不太可行。
2021-08-01 20:10:11 +08:00
回复了 O5oz6z3 创建的主题 Python 想请教几个有关 py3 的 exec、字节码和代码对象的问题
@ysc3839 确实,虽然可以通过替换覆盖 __builtins__ 模块内的内置函数来添加限制,但除了 __import__ 和 open 我也想不到哪里会不安全,的确又麻烦又容易遗漏。
用这个思路做沙盒确实很麻烦,可能方向不对,又或者是 python 在设计上本来就不打算支持沙盒功能。
2021-08-01 19:55:33 +08:00
回复了 O5oz6z3 创建的主题 Python 想请教几个有关 py3 的 exec、字节码和代码对象的问题
@hsfzxjy
>3. “构建任意函数”听上去似乎没有安全问题,因为在 exec 里面执行的代码字符串本来就可以随意定义函数,这个“任意函数”好像没有什么特别。
如果我没理解错的话,只是构造不正确的字节码让解释器崩溃,那么效果上似乎和递归溢出没有区别。
2021-08-01 19:52:37 +08:00
回复了 O5oz6z3 创建的主题 Python 想请教几个有关 py3 的 exec、字节码和代码对象的问题
@hsfzxjy 谢谢!
>1. 原来如此,我之前以为在 python3 中 exec 作为内置函数,可以通过覆盖 __builtins__ 来屏蔽掉,但是在 python2 中作为语句的 exec 就没办法屏蔽了,所以改成内置函数会安全些。

>2. 我去看看

>4. 明白了。不过这就已经超出 python 解释器的层面了,最初是想在脚本层面简单实现一个粗糙的隔离环境给 exec 运行。

不看不知道,一看吓一跳,这 __builtins__ 在很多标准库模块里都能获取到,泄露成筛子似的,看来确实很难在脚本层面实现简陋的沙箱。
罪魁祸首看来是 __subclasses__,也许可以归结于 python 本来就不注重属性的访问限制? python 在自省和透明的路上真是越走越远。
2021-07-31 17:41:04 +08:00
回复了 O5oz6z3 创建的主题 Python 如何评价生成器比推导式快?
@imn1 感谢回复……
关于 #18 楼提到的 #13 楼的问题,是我说得太含糊了,让人理解成本地变量名覆盖全局内置函数名称的软关键字问题。机会难得我就顺便补充一下。

举个例子:
iter = [1, 2, 3, 4]
iter = (x+2 for x in iter)
iter = (x+3 for x in iter)
以上代码中,第三行右侧的 `(x+3 for x in iter)` 表达式中的 iter 迭代时会展开为第二行右侧的生成器表达式 `(x+2 for x in iter)`。问题就是此时第二行右侧生成器中的 iter 指的是哪个 iter ?是 `(x+2 for x in iter)` 还是第一行的 [1, 2, 3, 4]?

后来实际验证了一下,答案是第一行的 [1, 2, 3, 4],也就是生成器表达式中的 iter 指向定义时候的 iter 变量的值,而不是执行的时候动态引用作用域中 iter 变量的值。有点像是闭包保存了定义时候的作用域。
2021-07-30 18:32:38 +08:00
回复了 LeeReamond 创建的主题 问与答 Cython 编译出的程序如何禁止异常冒泡?
@LeeReamond 我还以为触发异常泄露代码指的是异常堆栈打印,其他的方法我就不知道了。
2021-07-30 16:47:41 +08:00
回复了 LeeReamond 创建的主题 问与答 Cython 编译出的程序如何禁止异常冒泡?
不懂 cython 。说的是不是 sys.excepthook ?
2021-07-27 00:32:48 +08:00
回复了 O5oz6z3 创建的主题 Python 如何评价生成器比推导式快?
@fakepoet #14 我也觉得很有趣,虽然实际意义不大……
底层队列什么的我就不懂了,不过我的看法也和链接里的一样:通常情况下内存不是瓶颈,所以速度上推导式略胜一筹,但其实两者的差距非常小可以忽略不计。也就是推导式速度不是快很多,但生成器非常省内存。

@zachlhb #16 如果我没搞错的话,所谓的元组推导式正式名称就是生成器表达式,虽然生成器不止这一种写法。

@fakepoet @jaredyam #15 (可能这是 V2EX 特色,让用户在每次回复时摸索出真正的语法,增加趣味性)

顺带一提,#13 楼的写法又抛出了另一个问题:生成器表达式中的 iter 到底指向的是当时的值还是说引用全局标识符 iter ?如果是后者那么就乱套了……
2021-07-25 23:20:46 +08:00
回复了 O5oz6z3 创建的主题 Python 如何评价生成器比推导式快?
@O5oz6z3 #10
import timeit
_iter = list(range(12345))
init = 'iter = _iter'
end = 'iter = list(iter)'
maketest = lambda stmt, n: '\n'.join([init, *[stmt]*n, end])

comp = 'iter = [x**0.5 for x in iter]'
>>> timeit.timeit(maketest(comp, 3), number=100, globals=globals())
1.33
>>> timeit.timeit(maketest(comp, 10), number=100, globals=globals())
4.26

gene = 'iter = (x**0.5 for x in iter)'
>>> timeit.timeit(maketest(gene, 3), number=100, globals=globals())
1.63
>>> timeit.timeit(maketest(gene, 10), number=100, globals=globals())
4.60
2021-07-25 23:19:38 +08:00
回复了 O5oz6z3 创建的主题 Python 如何评价生成器比推导式快?
(测试)
comp = 'iter = [x**0.5 for x in iter]'
timeit.timeit(maketest(comp, 3), number=100, globals=globals())
2021-07-25 23:16:56 +08:00
回复了 O5oz6z3 创建的主题 Python 如何评价生成器比推导式快?
@O5oz6z3 #10
临时也想不出什么比较好的用来测试的逻辑:
import timeit
_iter = list(range(12345))
init = 'iter = _iter'
end = 'iter = list(iter)'
maketest = lambda stmt, n: '\n'.join([init, *[stmt]*n, end])
2021-07-25 23:12:06 +08:00
回复了 O5oz6z3 创建的主题 Python 如何评价生成器比推导式快?
@abersheeran
虽然看不懂,就指令的数量上来看,两者似乎没有差别。看起来性能差距微乎其微,初步测试了一下结果是生成器输了……
没想到 dis.dis 的递归反汇编功能要到 3.7 才出现。
1  2  3  4  5  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2723 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 70ms · UTC 10:04 · PVG 18:04 · LAX 02:04 · JFK 05:04
Developed with CodeLauncher
♥ Do have faith in what you're doing.