解析Hy宏中的参数

2024-09-22 16:31:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要帮助解析为类生成代码的Hy宏中的参数

我要完成的任务:一个宏,它将生成一个具有预定义属性的类。属性名是用于初始化类的变量

这是我到目前为止得到的

属性生成器

下面的函数为属性getter生成代码(约定为私有/内部变量使用__variable__名称)

(eval-and-compile
  (defn defproperty [attribute &optional docstring &rest body]
  `(with-decorator property
     (defn ~attribute [self]
       ~docstring
       (do ~@body)
       (return (getattr self (+ "__" (str '~attribute) "__")))))))

类生成器

下面的宏使用在__init__方法中传递的变量名为类生成代码

(defmacro/g! defrecord [recname inherits properties
                        &optional docstring &rest body]
  (setv g!properties% (-> (cut properties 1 (len properties) 2) (list)))

  `(defclass ~recname [~@inherits]

     ~docstring

     (defn __init__ [self ~@properties]
       (for [prop% '~g!properties%]
         (setattr self (+ "__" (str prop%) "__") (eval prop%))))

     ~@(lfor prop% g!properties% `(defproperty ~prop%))

     (do ~@body)))

测试用例

对于下面这种过于简单的情况,上述方法非常有效

(defrecord record [] (^(of float) data ^(of int) x ^(of str) doc))
(setv rec (record 2.0 3 "abc"))
(. rec doc) ;; => "abc"
(. rec info) ;; => 5.0

但对于更复杂的论点结构,它是失败的

  • (^(of float) data ^(of int) x &optional ^(of str) doc)
  • (^(of float) data ^(of int) x &kwonly ^(of str) [doc None])

这是因为宏中有以下语句

(setv g!properties% (-> (cut properties 1 (len properties) 2) (list)))

问题:如何对宏进行通用化,以适应更复杂的用例


Tags: of代码selfdatadoc属性bodyattribute