
暂无信息!
小于 1 分钟
在 golang 中有时候会需要用到类似其他语言中 enum 类型的通过值获取字段名称功能,通过以下脚本可以读取 go 文件中所有 全局 var/const 定义,并根据 值/iota值 生成 值:常量名 map。
import io
import regex
class Const:
const_name: str
const_value: str
def declare_str(self):
return f'\t{self.const_value}: "{self.const_name}",\n'
class ConstGroup:
const_type: str
const_list: list[Const]
map_keys: dict
def __init__(self):
self.map_keys = {}
self.const_list = []
def declare_str(self):
s = f'var {self.const_type}Map = map[{self.const_type}]string{{\n'
for c in self.const_list:
s += c.declare_str()
return s + "}\n"
const_map = {}
type_underlying = {}
with io.open("const.go", "rb") as f:
const_file = f.read().decode("utf-8")
lines = const_file.split("\n")
cursor_type = ""
const_syntax = False
iota = -1
# 自定义常量的前缀
trim_prefix_reg = regex.compile("^(?P<prefix>Clz|SV|BT|TD|SP|FM|SGP|PassType|ShaderCompilerPlatform).+")
# extract const
for line in lines:
params = [key.strip() for key in line.split(" ") if key != ""]
if not params:
continue
if params[0] == "type":
# type declare
type_underlying[params[1]] = params[2]
if params[0] == "const" and params[1] == "(":
# const definition
const_syntax = True
continue
elif params[0] == ")":
const_syntax = False
iota = -1
cursor_type = ""
if const_syntax:
const_name = params[0]
if len(params) == 4:
# type declared
const_type = params[1]
const_value = params[3]
if const_value == "iota":
cursor_type = const_type
iota = 0
const_value = iota.__str__()
iota += 1
else:
const_value = iota.__str__()
const_type = cursor_type
iota += 1
if const_name == "_":
continue
if const_type in const_map:
group = const_map[const_type]
else:
group = ConstGroup()
group.const_type = const_type
const_map[const_type] = group
if const_value in group.map_keys:
continue
# trim prefix
m = trim_prefix_reg.match(const_name)
if m:
prefix = m.group("prefix")
const_name = const_name.removeprefix(prefix)
# trim prefix type
if const_name.startswith(const_type):
const_name = const_name[len(const_type):]
group.map_keys[const_value] = True # avoid duplicated key
const = Const()
const.const_name = const_name
const.const_value = const_value
group.const_list.append(const)
print(f"ConstTypes: {type_underlying}")
# 修改包名
sb = "package unity\n\n"
sb += "// This is generated file. Do not modify.\n\n"
# write const
for k in const_map:
group = const_map[k]
sb += group.declare_str()
sb += "\n"
with io.open("const_map.go", "wb") as f:
f.write(sb.encode("utf-8"))
print("generated const_map.go")
在 python 迁移到 go 的过程中,面对已经成型的对象类定义,迁移和修改类定义不同于逻辑代码,是很枯燥痛苦的过程。
通过以下脚本文件可以实现快速转换。
使用注意
dict
字符串,可能被替换修改,如果出现该问题,请根据实际业务情况修改 map_go_type
方法。msg
tag 为我个人业务需求,可以直接删除或修改为其他tag。在 lazy=true
模式的 el-tree 中,节点通过 load
方法加载。如果有需要手动刷新节点数据的需求,可以使用以下方法:
return {
treeRootNode: null
}
先说结论。
在调用 stringify 之前把 Date 类型先格式化为字符串避免。
export default {
/**
* 解决 stringify 导致的时区丢失,提前把所有日期类型字段转化为字符串
* @param data 转换对象
* @returns {*}
*/
formatDateTime(data){
for (const key in data){
const value = data[key]
if (value instanceof Date) {
const year = value.getFullYear()
const month = (value.getMonth() < 9 ? '0' : '') + (value.getMonth() + 1)
const day = (value.getDate() < 10 ? '0' : '') + value.getDate()
const hour = (value.getHours() < 10 ? '0' : '') + value.getHours()
const minute = (value.getMinutes() < 10 ? '0' : '') + value.getMinutes()
const second = (value.getSeconds() < 10 ? '0' : '') + value.getSeconds()
const milliseconds = (value.getSeconds() < 100 ? value.getSeconds() < 10 ? '00' : '0' : '') + value.getSeconds()
data[key] = `${year}-${month}-${day}T${hour}:${minute}:${second}.${milliseconds}Z`
}
}
return data
}
}
今天使用 httpx/requests 对部分 httpx 网站进行访问,出现以下问题:
httpx.ConnectError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1002)
近几年为了解决一些不同项目的业务问题陆续开发了很多工具类。但是每次新建项目都要把这些工具类拽来拽去特别麻烦。 所以搞了一个工具包,提交到了中央仓库。每次新建项目的时候只需要引入依赖即可。
apt install -y ipset
//SpEL 解析器
SpelExpressionParser parser = new SpelExpressionParser();
//上下文数据
User user = new User();
user.setId(1);
user.setName("张三");
user.setCreateTime(LocalDate.now());
user.setAge(18);
user.setBalance(BigDecimal.TEN);
StandardEvaluationContext context = new StandardEvaluationContext(user);
//数值计算
System.out.println(parser.parseExpression("1+1").getValue()); //2
System.out.println(parser.parseExpression("age*(age+2)").getValue(context)); //360
System.out.println(parser.parseExpression("balance*2").getValue(context)); //20
System.out.println(parser.parseExpression("balance/2").getValue(context)); //5
System.out.println(parser.parseExpression("balance-3").getValue(context)); //7
System.out.println(parser.parseExpression("balance^2").getValue(context)); //100
//字符串拼接
System.out.println(parser.parseExpression("'name: '+name").getValue(context)); //name: 张三
//Map
System.out.println(parser.parseExpression("{name: name}").getValue(context)); //{name=张三}
//方法调用
System.out.println(parser.parseExpression("pow(balance, 4)").getValue(context)); //10000
//逻辑运算
System.out.println(parser.parseExpression("balance > 20").getValue(context)); //false
System.out.println(parser.parseExpression("balance == 20 or balance == 10").getValue(context)); //true
System.out.println(parser.parseExpression("balance == 10 and balance < age").getValue(context)); //true
package cn.doblue.assetsana.utils.data;
import java.security.SecureRandom;
/**
* 随机工具类
*/
public class RandomUtil {
public static String ALPHANUMERIC = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890qwertyuiopasdfghjklzxcvbnm";
private final static SecureRandom random = new SecureRandom();
/**
* 生成随机字母数字
* @param length 长度
* @return 随机字母字符串
*/
public static String randomAlphanumeric(int length){
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(ALPHANUMERIC.charAt(random.nextInt(ALPHANUMERIC.length())));
}
return sb.toString();
}
/**
* 随机 0 - size 的整数
*/
public static Integer randomInt(int size) {
return random.nextInt(size);
}
}