从 for 循环生成代码的宏
Macros that generate code from a for-loop
这个例子有点做作。目标是创建一个循环遍历某些值并以编程方式生成一些代码的宏。
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
形式总是 return None
。因此,您的循环正在构建您请求的 (setv ...)
表单,然后将它们丢弃。相反,请尝试 lfor
,其中 return 是结果列表,或者 gfor
,return 是生成器。另请注意,在下面的示例中,我使用 do
将生成的表单组合在一起,并且我移动了 ~
以便 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
这个例子有点做作。目标是创建一个循环遍历某些值并以编程方式生成一些代码的宏。
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
形式总是 return None
。因此,您的循环正在构建您请求的 (setv ...)
表单,然后将它们丢弃。相反,请尝试 lfor
,其中 return 是结果列表,或者 gfor
,return 是生成器。另请注意,在下面的示例中,我使用 do
将生成的表单组合在一起,并且我移动了 ~
以便 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