- 积分
- 3521
- 明经币
- 个
- 注册时间
- 2010-9-4
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 wyl219 于 2020-10-2 00:49 编辑
实际是看到http://bbs.mjtd.com/thread-182383-1-1.html里的一个想法,把变量的内容保存到文件内,方便将来读取.
其实网上已经有现成的方法了,即保存到ini文件里,参见:https://blog.csdn.net/yxp_xa/article/details/72539877
vectra大佬提出了一个想法,直接保存为lsp文件,用的时候直接read一下,之前没考虑过这方面的内容,确实是个不错的选择.
不过这个办法有个缺点,就是不能选择性的加载内容,因此花了点时间写了两个小函数,没经过很详细的测试,只知道不能用于保存匿名函数.带了两个示例程序.比较特别的是,函数运行后,会直接把变量的值赋给保存的变量名,而不需要像ini文件那样,需要外嵌一个setq函数,确定就是不能随时修改变量名.
希望能让更多人看到讨论,单独发了个帖子.
;|
说明:
示例程序:导出变量
|;
(defun c:tt1 ( / file_name a b c d e )
(setq file_name "d:\\test.setting");可以设定为全局变量或局部变量,当设定为局部变量时,可用于每个程序保存为独立的文件.
(setq a 1 ;数字变量
b "2" ;字符串变量
c (list 1 2 "a") ;列表变量
d 'list ;函数变量,可能只能用于系统自带函数
e '(lambda nil 1) ;用户函数变量,实际上是个列表
; 如果不加前面的',作为匿名函数,保存的是函数的id,实际上是不能读取的
);初始化变量
(wyl:save_var "d:\\test.setting" (list "a" "b" "c" "d" "e") "" )
(getstring "已保存变量a至e,按空格键继续")
(setq a 3
b "1"
);修改变量
(wyl:save_var "d:\\test.setting" "a" "up" )
(getstring "已更新变量a的值,按空格键继续")
(wyl:save_var "d:\\test.setting" "c" "" )
(princ "已保存变量b,并删除其他内容")
(wyl:save_var "d:\\test.setting" (list "a" "b" "c" "d" "e") "" )
(princ "示例程序结束,并重新保存所有变量,用于示例2")
)
;|
说明:
示例程序:导入变量
|;
(defun c:tt2 ( / file_name a b c d e f g )
(setq file_name "d:\\test.setting");可以设定为全局变量或局部变量,当设定为局部变量时,可用于每个程序保存为独立的文件.
(print "之前各项的值(应该均为nil):")
(print (strcat "a:" (vl-princ-to-string a) "type:" (vl-princ-to-string (type a))))
(print (strcat "b:" (vl-princ-to-string b) "type:" (vl-princ-to-string (type b))))
(print (strcat "c:" (vl-princ-to-string c) "type:" (vl-princ-to-string (type c))))
(print (strcat "d:" (vl-princ-to-string d) "type:" (vl-princ-to-string (type d))))
(print (strcat "e:" (vl-princ-to-string e) "type:" (vl-princ-to-string (type e))))
(print (strcat "f:" (vl-princ-to-string f) "type:" (vl-princ-to-string (type f))))
(getstring "导入各项变量,并且不获取未找到的变量\n")
(wyl:load_var "d:\\test.setting" (list "a" "b" "c" "d" "e" "f") nil )
(print (strcat "a:" (vl-princ-to-string a) "type:" (vl-princ-to-string (type a))))
(print (strcat "b:" (vl-princ-to-string b) "type:" (vl-princ-to-string (type b))))
(print (strcat "c:" (vl-princ-to-string c) "type:" (vl-princ-to-string (type c))))
(print (strcat "d:" (vl-princ-to-string d) "type:" (vl-princ-to-string (type d))))
(print (strcat "e:" (vl-princ-to-string e) "type:" (vl-princ-to-string (type e))))
(print (strcat "f:" (vl-princ-to-string f) "type:" (vl-princ-to-string (type f))))
(print "b应该是str,c、e是list,d是SYM,f应该是nil")
(getstring "导入未找到的变量f,并用默认获取方式(即getstring)\n")
(wyl:load_var "d:\\test.setting" "f" "" )
(print (strcat "f:" (vl-princ-to-string f) "type:" (vl-princ-to-string (type f))))
(getstring "导入未找到的变量f,并用getint获取方式(获取到的数据类型是int)\n")
(wyl:load_var "d:\\test.setting" "f" '(getint "f的数值") )
(print (strcat "f:" (vl-princ-to-string f) "type:" (vl-princ-to-string (type f))))
(getstring "导入未找到的变量f,并用字符串函数获取\n")
(wyl:load_var "d:\\test.setting" "f" "(getint \"f的大小\")" )
(print (strcat "f:" (vl-princ-to-string f) "type:" (vl-princ-to-string (type f))))
(getstring "导入未找到的变量f、g,并用字符串函数获取,例如需要获取为int并且想使用默认的提示语\n")
(wyl:load_var "d:\\test.setting" '("f" "g") "(getint msg)" )
(print (strcat "f:" (vl-princ-to-string f) "type:" (vl-princ-to-string (type f))))
(print (strcat "g:" (vl-princ-to-string g) "type:" (vl-princ-to-string (type g))))
(getstring "导入未找到的变量f、g,并用自定函数获取,例如需要将输入的数值乘以1000\n")
(wyl:load_var "d:\\test.setting" '("f" "g") '(lambda nil (* 1000 (getreal "输入米数"))) )
(print (strcat "f:" (vl-princ-to-string f) "type:" (vl-princ-to-string (type f))))
(print (strcat "g:" (vl-princ-to-string g) "type:" (vl-princ-to-string (type g))))
)
;|
说明:
参数:file_path:文件的绝对路径,或当文件在支持文件中时可以是文件名,路径中的\用\\代替
var_list:需要导出的变量名列表,注意,是变量名,而不是变量,即"a"这样的字符串形式.当只有一个变量的时候可以用字符串而不是列表
mode:保存模式.当mode为"up"时,会保留除此次保存的变量之外的其他变量,否则将只保留本次保存的变量.
返回值:t
示例:
保存a b c 三个变量到文件
(wyl:save_var "d:\\test.setting" (list "a" "b" "c") )
更新a b 变量到文件
(wyl:save_var "d:\\test.setting" (list "a" "b") "up")
保存 a 变量到文件,并不保留其他内容
(wyl:save_var "d:\\test.setting" "a" "" )
|;
(defun wyl:save_var( file_path var_list mode / fn bo new_var_list this )
(if (eq 'str (type var_list))
(setq var_list (list var_list))
); var_list如果是字符串,则转换成列表
(if (eq mode "up")
(progn
; 开始读取原有配置
(setq fn (open file_path "r"))
(setq new_var_list '())
(while (setq this (read-line fn));当文件读完以后 read-line返回nil
(setq new_var_list (cons this new_var_list))
)
(close fn) ; 关闭文件
(foreach x var_list ;循环x=需要保存的变量
(setq bo t) ; 临时变量,当bo=t表示未在原有记录中找到x变量
(foreach y new_var_list; 循环 y=原有变量中的每一个条目
(if (wcmatch y (strcat "(setq " x " *"))
(progn
(setq new_var_list (cons
(strcat "(setq " x " '" (vl-prin1-to-string (eval (read x))) ")")
;拼成(setq a 1)的形式,read和eval均不能少
;当变量为字符串类型时,prin1的形式是"1",princ的形式是1,即princ导出的字符串是错误的
;变量内容前会加一个',否则当变量内容是表时,read-eval后,会把这部分当成一个函数处理
(vl-remove y new_var_list); 从列表中删除原有条目
)
)
(setq bo nil) ;找到变量后跳过下一步
)
)
) ; end foreach y
(if bo (setq new_var_list (cons
(strcat "(setq " x " '" (vl-prin1-to-string (eval (read x))) ")")
new_var_list
))
);如果没在原记录中找到对应项,则单独加入
); end foreach x
) ;end progn
(progn ;当mode不等于up时
(setq new_var_list '())
(foreach x var_list
(setq new_var_list (cons
(strcat "(setq " x " '" (vl-prin1-to-string (eval (read x))) ")")
new_var_list
)
)
)
);end progn
);end if
; 开始写入配置文件
(setq fn (open file_path "w"))
(foreach x new_var_list
(write-line x fn)
)
(close fn)
t ;返回t
)
;|
说明:
参数:file_path:文件的绝对路径,或当文件在支持文件中时可以是文件名,路径中的\用\\代替
var_list:需要导入的变量名列表,注意,是变量名,而不是变量,即"a"这样的字符串形式.当只有一个变量的时候可以用字符串而不是列表,当需要导入所有变量时,var_list可以是空字符串、"*"或nil.
fun:当未找到变量时,如何处理,当fun=nil时,不处理,当fun为字符串或函数时按照内容处理,当fun为空字符串时,采用默认处理方式,当字符串形式的代码时,如果代码中有引号,需要用\"代替
返回值:t
示例:
从文件中读取变量a,当文件中无a的记录时,不获取值
(wyl:load_var "d:\\test.setting" "a" nil )
从文件中读取变量a 和b ,当文件每无相应的记录时,通过默认方式获取值
(wyl:load_var "d:\\test.setting" (list "a" "b") "" )
从文件中读取变量a,当文件中无a的记录时,通过给定的函数处理
(wyl:load_var "d:\\test.setting" "a" '(getint "输入高度") )
从文件中读取变量a 和b ,当文件每无相应的记录时,通过字符串函数获取值
(wyl:load_var "d:\\test.setting" (list "a" "b") "(getint \"输入高度\")" )
|;
(defun wyl:load_var(file_path var_list fun / fn new_var_list bo msg)
; 格式化参数
(cond
((or (eq "" var_list) (not var_list))
(setq var_list '("*"))
)
((eq 'str (type var_list))
(setq var_list (list var_list))
)
(t)
);end cond
(if (eq fun "")
(setq fun "(getstring msg)")
)
; 开始原有配置
(setq fn (open file_path "r"))
(setq new_var_list '())
(while (setq this (read-line fn));当文件读完以后 read-line返回nil
(setq new_var_list (cons this new_var_list))
)
(close fn) ; 关闭文件
;开始应用配置
(foreach x var_list
(foreach y new_var_list
(setq bo t)
(if (wcmatch y (strcat "(setq " x " *"));如果是要恢复的条目,注意这里的判断和save里的判断和保存的形式需要相同
(progn
(eval (read y))
(setq bo nil)
)
);end if
); end foreach y
(if (and bo fun (not (eq "*" x))) ;当没有找到变量,并且变量不为*时,由用户输入变量
(if (or (eq 'list (type fun)) (eq 'SUBR (type fun)))
(set (read x) (eval fun)); 如果fun是个函数
(progn ; 如果fun是个字符串
(setq msg (strcat"请输入变量" x "的值:"))
(set (read x) (eval (read fun)));这里是set而不是setq
);end progn
) ;end if
);end if
); end foreach x
t ;返回t
)
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
评分
-
查看全部评分
|