簡體   English   中英

從 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 和 dataclasses。 但作為一個簡化的學習練習,我想用宏來解決這個問題。

這是我的非工作示例:

(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

Wbat我做錯了嗎?

for表單總是返回None 因此,您的循環正在構建您請求的(setv ...)表單,然后將它們扔掉。 相反,嘗試lfor ,返回結果,或列表gfor ,它返回一個發電機。 還要注意在下面的示例中,我使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM