hy - 从 for 循环生成代码的宏
问题描述
这个例子有点做作。目标是创建一个循环遍历某些值并以编程方式生成一些代码的宏。
Python 中的一个常见模式是在调用时初始化对象的属性,如下所示:
(defclass hair [foo bar]
(defn __init__ [self]
(setv self.foo foo)
(setv self.bar bar)))
这正确地转换hy2py
为
class hair(foo, bar):
def __init__(self):
self.foo = foo
self.bar = bar
return None
我知道有解决这个问题的 Python 方法,包括 attr.ib 和数据类。但作为一个简化的学习练习,我想用一个宏来解决这个问题。
这是我的非工作示例:
(defmacro self-set [&rest args]
(for [[name val] args]
`(setv (. self (read-str ~name)) ~val)))
(defn fur [foo bar]
(defn __init__ [self]
(self-set [["foo" foo] ["bar" bar]])))
但这并没有扩展到原始模式。hy2py
显示:
from hy.core.language import name
from hy import HyExpression, HySymbol
import hy
def _hy_anon_var_1(hyx_XampersandXname, *args):
for [name, val] in args:
HyExpression([] + [HySymbol('setv')] + [HyExpression([] + [HySymbol
('.')] + [HySymbol('self')] + [HyExpression([] + [HySymbol(
'read-str')] + [name])])] + [val])
hy.macros.macro('self-set')(_hy_anon_var_1)
def fur(foo, bar):
def __init__(self, foo, bar):
return None
我做错了吗?
解决方案
for
表格总是返回None
。因此,您的循环正在构建(setv ...)
您请求的表单,然后将它们丢弃。取而代之的是 try lfor
,它返回一个结果列表,或者gfor
,它返回一个生成器。另请注意,在下面的示例中,我使用do
将生成的表单分组在一起,并且我已经移动了 a~
以便read-str
在编译时发生,因为它必须为了.
工作。
(defmacro self-set [&rest args]
`(do ~@(gfor
[name val] args
`(setv (. self ~(read-str name)) ~val))))
(defclass hair []
(defn __init__ [self]
(self-set ["foo" 1] ["bar" 2])))
(setv h (hair))
(print h.bar) ; 2
推荐阅读
- angularjs - 错误:未捕获的 ReferenceError:角度未在 controllers.js:1 中定义
- c++ - 是否存在表达式 `ab::c` 有意义的上下文?
- ios - 如何在场景中添加按钮和标签
- scala - Scala如何在元组中指定元组的返回类型
- actions-on-google - 播客被谷歌索引,但不在助理目录中。该怎么办?
- angular - 为什么我的一些延迟加载的模块找不到而其他的可以?
- export - .fex 文件中有什么失败?
- powerbi - 从饼图的一个切片导航到另一个饼图
- dart - 如何在 Flutter 中处理密码中的 TextField 验证
- python - calculate depth from two images with epipolar geometry?