kevin-toolbox-dev 1.0.10b0__py3-none-any.whl → 1.0.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. kevin_toolbox/__init__.py +2 -2
  2. kevin_toolbox/computer_science/algorithm/combinatorial_optimization/test/test_get_subset_with_largest_product.py +1 -1
  3. kevin_toolbox/computer_science/algorithm/combinatorial_optimization/test/test_zero_one_knapsack_problem.py +1 -1
  4. kevin_toolbox/computer_science/algorithm/for_nested_dict_list/__init__.py +6 -0
  5. kevin_toolbox/computer_science/algorithm/for_nested_dict_list/count_leaf_node_nums.py +21 -0
  6. kevin_toolbox/computer_science/algorithm/for_nested_dict_list/get_leaf_nodes.py +22 -0
  7. kevin_toolbox/computer_science/algorithm/{utils → for_nested_dict_list}/get_value_by_name.py +0 -5
  8. kevin_toolbox/computer_science/algorithm/{utils → for_nested_dict_list}/set_value_by_name.py +25 -19
  9. kevin_toolbox/computer_science/algorithm/{utils → for_nested_dict_list}/traverse.py +21 -24
  10. kevin_toolbox/computer_science/algorithm/registration/__init__.py +1 -0
  11. kevin_toolbox/computer_science/algorithm/registration/registry.py +232 -0
  12. kevin_toolbox/computer_science/algorithm/scheduler/strategy_manager.py +1 -1
  13. kevin_toolbox/computer_science/algorithm/utils/__init__.py +0 -4
  14. kevin_toolbox/data_flow/file/json_/write_json.py +1 -1
  15. kevin_toolbox/developing/design_pattern/singleton/singleton_for_uid.py +7 -1
  16. {kevin_toolbox_dev-1.0.10b0.dist-info → kevin_toolbox_dev-1.0.12.dist-info}/METADATA +10 -11
  17. {kevin_toolbox_dev-1.0.10b0.dist-info → kevin_toolbox_dev-1.0.12.dist-info}/RECORD +25 -20
  18. /kevin_toolbox/computer_science/algorithm/{utils/for_dict → for_dict}/__init__.py +0 -0
  19. /kevin_toolbox/computer_science/algorithm/{utils/for_dict → for_dict}/deep_update.py +0 -0
  20. /kevin_toolbox/computer_science/algorithm/{utils → for_nested_dict_list}/get_hash.py +0 -0
  21. /kevin_toolbox/computer_science/algorithm/{utils/for_seq → for_seq}/__init__.py +0 -0
  22. /kevin_toolbox/computer_science/algorithm/{utils/for_seq → for_seq}/flatten_list.py +0 -0
  23. /kevin_toolbox/computer_science/algorithm/{utils/for_seq → for_seq}/get_subsets.py +0 -0
  24. {kevin_toolbox_dev-1.0.10b0.dist-info → kevin_toolbox_dev-1.0.12.dist-info}/WHEEL +0 -0
  25. {kevin_toolbox_dev-1.0.10b0.dist-info → kevin_toolbox_dev-1.0.12.dist-info}/top_level.txt +0 -0
kevin_toolbox/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "1.0.10b"
1
+ __version__ = "1.0.12"
2
2
 
3
3
 
4
4
  import os
@@ -12,5 +12,5 @@ os.system(
12
12
  os.system(
13
13
  f'python {os.path.split(__file__)[0]}/env_info/check_validity_and_uninstall.py '
14
14
  f'--package_name kevin-toolbox-dev '
15
- f'--expiration_timestamp 1701361536 --verbose 0'
15
+ f'--expiration_timestamp 1702197528 --verbose 0'
16
16
  )
@@ -2,7 +2,7 @@ import pytest
2
2
  import numpy as np
3
3
  from kevin_toolbox.patches.for_test import check_consistency
4
4
  from kevin_toolbox.computer_science.algorithm.combinatorial_optimization import get_subset_with_largest_product
5
- from kevin_toolbox.computer_science.algorithm.utils.for_seq import get_subsets
5
+ from kevin_toolbox.computer_science.algorithm.for_seq import get_subsets
6
6
 
7
7
 
8
8
  def test_get_subset_with_largest_product():
@@ -2,7 +2,7 @@ import pytest
2
2
  import numpy as np
3
3
  from kevin_toolbox.patches.for_test import check_consistency
4
4
  from kevin_toolbox.computer_science.algorithm.combinatorial_optimization import zero_one_knapsack_problem
5
- from kevin_toolbox.computer_science.algorithm.utils.for_seq import get_subsets
5
+ from kevin_toolbox.computer_science.algorithm.for_seq import get_subsets
6
6
 
7
7
 
8
8
  def test_zero_one_knapsack_problem():
@@ -0,0 +1,6 @@
1
+ from .get_hash import get_hash
2
+ from .traverse import traverse
3
+ from .get_value_by_name import get_value_by_name
4
+ from .set_value_by_name import set_value_by_name
5
+ from .count_leaf_node_nums import count_leaf_node_nums
6
+ from .get_leaf_nodes import get_leaf_nodes
@@ -0,0 +1,21 @@
1
+ from kevin_toolbox.computer_science.algorithm.for_nested_dict_list import traverse
2
+
3
+
4
+ def count_leaf_node_nums(var):
5
+ """
6
+ 获取嵌套字典列表 var 中所有叶节点的数量
7
+
8
+ 参数:
9
+ var: 待处理数据
10
+ 当 var 不是 dict 或者 list 时,直接将 var 视为根节点,叶节点数量视为 0
11
+ """
12
+ nums = 0
13
+
14
+ def count(_, __, v):
15
+ nonlocal nums
16
+ if not isinstance(v, (list, dict,)):
17
+ nums += 1
18
+ return False
19
+
20
+ traverse(var=var, match_cond=count, action_mode="skip", b_use_name_as_idx=False)
21
+ return nums
@@ -0,0 +1,22 @@
1
+ from kevin_toolbox.computer_science.algorithm.for_nested_dict_list import traverse
2
+
3
+
4
+ def get_leaf_nodes(var):
5
+ """
6
+ 获取嵌套字典列表 var 中所有叶节点
7
+ 以列表 [(name,value), ...] 形式返回,其中名字 name 的解释方式参考 get_value_by_name() 介绍
8
+
9
+ 参数:
10
+ var: 待处理数据
11
+ 当 var 不是 dict 或者 list 时,返回空列表
12
+ """
13
+ res = []
14
+
15
+ def func(_, idx, v):
16
+ nonlocal res
17
+ if not isinstance(v, (list, dict,)):
18
+ res.append((idx, v))
19
+ return False
20
+
21
+ traverse(var=var, match_cond=func, action_mode="skip", b_use_name_as_idx=True)
22
+ return res
@@ -42,8 +42,3 @@ def get_value_by_name(var, name):
42
42
  var = var[key]
43
43
 
44
44
  return var
45
-
46
-
47
- if __name__ == '__main__':
48
- print(get_value_by_name(var=dict(acc=[0.66, 0.78, 0.99]), name="|acc|0"))
49
- print(get_value_by_name(var=dict(acc=[0.66, 0.78, 0.99]), name="www|acc|0"))
@@ -1,12 +1,12 @@
1
- from kevin_toolbox.computer_science.algorithm.utils import get_value_by_name
1
+ from kevin_toolbox.computer_science.algorithm.for_nested_dict_list import get_value_by_name
2
2
 
3
3
 
4
- def set_value_by_name(var, name, value):
4
+ def set_value_by_name(var, name, value, b_force=False):
5
5
  """
6
6
  通过解释名字得到取值方式,然后到 var 中将对应部分的值修改为 value。
7
7
 
8
8
  参数:
9
- var: 任意支持索引取值的变量
9
+ var: 任意支持索引赋值的变量
10
10
  name: <string> 取值方式
11
11
  由多组 "<解释方式><键>" 组成。
12
12
  解释方式支持以下几种:
@@ -22,6 +22,9 @@ def set_value_by_name(var, name, value):
22
22
  注意,在 name 的开头也可以添加任意非解释方式的字符,本函数将直接忽略它们,比如下面的:
23
23
  "var:acc@1" 和 "xxxx|acc|1" 也能正常写入。
24
24
  value: 待赋给的值
25
+ b_force: <boolean> 当无法设置时,是否尝试创建或者修改节点
26
+ 默认为 False,
27
+ 当设置为 True,可能会对 var 的结构产生不可逆的改变,请谨慎使用。新创建或者修改的节点的类型是 dict。
25
28
  """
26
29
  assert isinstance(name, (str,))
27
30
  key = name
@@ -29,21 +32,24 @@ def set_value_by_name(var, name, value):
29
32
  key = key.rsplit(char, 1)[-1]
30
33
  assert len(key) < len(name), f'invalid name: {name}'
31
34
 
32
- item = get_value_by_name(var=var, name=name[:-1 - len(key)])
35
+ try:
36
+ item = get_value_by_name(var=var, name=name[:-1 - len(key)])
37
+
38
+ flag = name[-1 - len(key)]
39
+ key_t = key
40
+ if flag == "@":
41
+ key_t = eval(key)
42
+ elif flag == "|":
43
+ try:
44
+ _ = item[key]
45
+ except:
46
+ key_t = eval(key)
47
+
48
+ item[key_t] = value
49
+ except:
50
+ if not b_force:
51
+ raise ValueError(f'The location pointed to by name {name} does not exist in var')
52
+ else:
53
+ var = set_value_by_name(var=var, name=name[:-1 - len(key)], value={key: value}, b_force=b_force)
33
54
 
34
- flag = name[-1 - len(key)]
35
- if flag == "@":
36
- key = eval(key)
37
- elif flag == "|":
38
- try:
39
- _ = item[key]
40
- except:
41
- key = eval(key)
42
-
43
- item[key] = value
44
55
  return var
45
-
46
-
47
- if __name__ == '__main__':
48
- print(set_value_by_name(var=dict(acc=[0.66, 0.78, 0.99]), name="|acc|0", value=1))
49
- print(set_value_by_name(var=dict(acc=[0.66, 0.78, 0.99]), name="www|acc|0", value=1))
@@ -1,4 +1,4 @@
1
- def traverse(var, match_cond, action_mode="remove", converter=None):
1
+ def traverse(var, match_cond, action_mode="remove", converter=None, b_use_name_as_idx=False):
2
2
  """
3
3
  遍历 var 找到符合 match_cond 的元素,将其按照 action_mode 指定的操作进行处理
4
4
 
@@ -9,51 +9,48 @@ def traverse(var, match_cond, action_mode="remove", converter=None):
9
9
  函数类型为 def(parent_type, idx, value): xxxx
10
10
  其中:
11
11
  parent_type 该元素源自哪种结构体,有两个可能传入的值: list,dict
12
- idx 该元素在结构体中的位置,对于列表是 index,对于字典是 key
12
+ idx 该元素在结构体中的位置
13
+ 当 b_use_name_as_idx=False 时,
14
+ 对于列表是 index,对于字典是 key
15
+ 当为 True 时,传入的是元素在整体结构中的 name 位置,name的格式和含义参考
16
+ get_value_by_name() 中的介绍
13
17
  value 元素的值
14
18
  action_mode: <str> 如何对匹配上的元素进行处理
15
19
  目前支持:
16
20
  "remove" 将该元素移除
17
21
  "replace" 将该元素替换为 converter() 处理后的结果
22
+ "skip": 不进行任何操作
18
23
  converter: <func> 参见 action_mode 中的 "replace" 模式
19
24
  函数类型为 def(idx, value): xxxx
20
25
  其中 idx 和 value 的含义参见参数 match_cond 介绍
26
+ b_use_name_as_idx <boolean> 对于 match_cond/converter 中的 idx 参数,是传入整体的 name 还是父节点的 index 或 key。
27
+ 默认为 False
21
28
  """
22
29
  assert callable(match_cond)
23
- assert action_mode in {"replace", "remove"}
30
+ assert action_mode in {"replace", "remove", "skip"}
24
31
  if action_mode == "replace":
25
32
  assert callable(converter)
26
33
 
27
- return recursive_(var, match_cond, action_mode, converter)
34
+ return recursive_(var, match_cond, action_mode, converter, b_use_name_as_idx, "")
28
35
 
29
36
 
30
- def recursive_(var, match_cond, action_mode, converter):
37
+ def recursive_(var, match_cond, action_mode, converter, b_use_name_as_idx, pre_name):
31
38
  if isinstance(var, (list, dict)):
32
39
  items = reversed(list(enumerate(var))) if isinstance(var, list) else list(var.items())
33
40
  for k, v in items:
34
- if match_cond(type(var), k, v):
41
+ if b_use_name_as_idx:
42
+ idx = f'{pre_name}@{k}' if isinstance(var, list) else f'{pre_name}:{k}'
43
+ else:
44
+ idx = k
45
+ if match_cond(type(var), idx, v):
35
46
  if action_mode == "remove":
36
47
  var.pop(k)
48
+ elif action_mode == "replace":
49
+ var[k] = converter(idx, v)
37
50
  else:
38
- var[k] = converter(k, v)
51
+ pass
39
52
  else:
40
- var[k] = recursive_(v, match_cond, action_mode, converter)
53
+ var[k] = recursive_(v, match_cond, action_mode, converter, b_use_name_as_idx, idx)
41
54
  else:
42
55
  pass
43
56
  return var
44
-
45
-
46
- if __name__ == '__main__':
47
- import numpy as np
48
-
49
- x = [
50
- dict(d=3, c=4),
51
- np.array([[1, 2, 3]])
52
- ]
53
-
54
- y1 = traverse(var=x, match_cond=lambda _, k, v: type(v) is np.ndarray, action_mode="replace",
55
- converter=lambda k, v: v.tolist())
56
- print(y1)
57
-
58
- y2 = traverse(var=y1, match_cond=lambda _, k, v: v == 3, action_mode="remove")
59
- print(y2)
@@ -0,0 +1 @@
1
+ from .registry import Registry, UNIFIED_REGISTRY
@@ -0,0 +1,232 @@
1
+ import re
2
+ import inspect
3
+ import pkgutil
4
+ import weakref
5
+ from kevin_toolbox.computer_science.algorithm.for_nested_dict_list import get_value_by_name, set_value_by_name, \
6
+ traverse, count_leaf_node_nums
7
+
8
+
9
+ class Registry:
10
+ """
11
+ 注册器
12
+ 具有以下功能
13
+ - 管理成员,包括添加 add()、获取 get() pop() 成员等
14
+ - 支持通过装饰器 register() 来添加成员
15
+ - 支持通过 collect_from() 搜索指定的路径,当该路径下的模块被 register() 装饰器包裹时,将自动导入(用于解决python中的模块是惰性的问题)
16
+
17
+ 使用方法:
18
+ 以目录结构:
19
+ xx/——— modules_dir
20
+ | |——— a.py
21
+ | |___ ...
22
+ |——— test.py
23
+ 为例。
24
+ 我们的目标是在 test.py 中,构建一个能够自动加载 modules_dir 中待注册成员的 Registry 实例。
25
+ 具体步骤如下:
26
+ 1. 在文件 test.py 中:
27
+ # 创建注册器实例
28
+ DB = Registry(uid="DB")
29
+ # 设置搜索路径
30
+ DB.collect_from(path_ls=["xx/modules_dir"])
31
+
32
+ 2. 在 modules_dir 下需要加载的成员中,以 a.py 为例:
33
+ # 导入注册器实例
34
+ from xx.test import DB
35
+ # 使用 DB.register() 装饰器注册
36
+ @DB.register(name=":my_module")
37
+ class A:
38
+ ...
39
+ # 使用 add() 函数注册
40
+ DB.add(obj=233, name=":var:c")
41
+
42
+ 3. 在文件 test.py 中:
43
+ # 获取已注册成员
44
+ module = DB.get(name=":my_module")
45
+
46
+ 4. 如果需要在其他文件中获取已有注册器实例,除了用 import 之外,还可以直接用 uid
47
+ # 获取指定 uid 下的实例
48
+ temp = Registry(uid="DB")
49
+ """
50
+ name = "registry made by kevin"
51
+ __instances = weakref.WeakValueDictionary() # {uid: instance_i, ...} 用于保存创建的实例
52
+ __counter = 0
53
+
54
+ def __new__(cls, *args, **kwargs):
55
+ """
56
+ __new__函数返回的实例,将作为self参数被传入到__init__函数。
57
+ 如果__new__函数返回一个已经存在的实例(不论是哪个类的),__init__还是会被调用的,所以要特别注意__init__中对变量的赋值。
58
+ """
59
+ uid = kwargs.get("uid", cls.__counter)
60
+
61
+ # 获取实例
62
+ if uid in cls.__instances:
63
+ # 返回已存在的实例
64
+ self = cls.__instances[uid]
65
+ else:
66
+ # 传入 __init__ 中新建一个实例
67
+ self = super().__new__(cls)
68
+ return self
69
+
70
+ def __init__(self, *args, **kwargs):
71
+ """
72
+ 参数:
73
+ uid: <hashable> 实例的唯一标识符
74
+ 默认置空,此时将新建一个实例,并将此时已有实例的数量作为 uid
75
+ 当为非空,则根据 uid 到已有实例中寻找相同的实例,并返回(使用该特性可以构造单例模式)
76
+ """
77
+ try:
78
+ getattr(self, "uid")
79
+ except:
80
+ pass
81
+ else:
82
+ return # 如果是从 __new__ 中获取的已有的实例则不重复进行参数赋值
83
+ self.database = dict()
84
+ #
85
+ self.uid = kwargs.get("uid", Registry.__counter)
86
+ self.inactivate_b_force_of_add = False
87
+ # 记录到 __instances 中
88
+ Registry.__instances[self.uid] = self
89
+ Registry.__counter += 1
90
+
91
+ def add(self, obj, name=None, b_force=False):
92
+ """
93
+ 注册
94
+
95
+ 参数:
96
+ obj: 待注册成员
97
+ 可以是函数、类或者callable的实例
98
+ 也可以是各种 int、float、str变量
99
+ 总之一切对象皆可
100
+ name: <str> 成员名称
101
+ 默认为 None,此时将从被注册对象 obj 的属性中尝试推断出其名称。
102
+ 若 obj 中有 name 或者 __name__ 属性(优先选择name),则推断出的名称是 f':{obj.name}';
103
+ 进一步若有 version 属性,则为 f':{obj.name}:{obj.version}'
104
+ 否则报错。
105
+ 比如下面的类:
106
+ class A:
107
+ version="1.0"
108
+ 的默认注册名称将是 ":A:1.0"
109
+ 对于 int、str 和其他没有 name 或者 __name__ 属性的变量则必须要手动指定 name 参数。
110
+ 需要注意的是,成员的名称确定了其在注册器内部 database 中的位置,名称的解释方式参考 get_value_by_name() 中的介绍。
111
+ 因此不同的名称可能指向了同一个位置。
112
+ b_force: <boolean> 是否强制注册
113
+ 默认为 False,此时当 name 指向的位置上已经有成员时,将不进行覆盖而直接报错
114
+ 当设置为 True,将会强制覆盖
115
+ """
116
+ # 检验参数
117
+ if name is None:
118
+ name = getattr(obj, "name", getattr(obj, "__name__", None))
119
+ if name is not None:
120
+ name = f':{name}'
121
+ version = getattr(obj, "version", None)
122
+ if version is not None:
123
+ name += f':{version}'
124
+ assert isinstance(name, (str,))
125
+
126
+ # 尝试注册
127
+ temp = self.database.copy()
128
+ set_value_by_name(var=temp, name=name, value=obj, b_force=True)
129
+ # check
130
+ if not self.inactivate_b_force_of_add and not b_force:
131
+ inc_node_nums = count_leaf_node_nums(var=obj) if isinstance(obj, (list, dict)) else 1 # 增加的节点数量
132
+ assert count_leaf_node_nums(var=temp) == count_leaf_node_nums(var=self.database) + inc_node_nums, \
133
+ f'registration failed, it may be a conflict with an existing member'
134
+ self.database = temp
135
+
136
+ def get(self, name, **kwargs):
137
+ """
138
+ 获取
139
+
140
+ 参数:
141
+ name: <str> 成员名称
142
+ default: 默认值
143
+ 找不到时,若无默认值则报错,否则将返回默认值
144
+ """
145
+ try:
146
+ return get_value_by_name(var=self.database, name=name)
147
+ except:
148
+ if "default" in kwargs:
149
+ return kwargs["default"]
150
+ else:
151
+ raise AssertionError(f'element {name} not exists')
152
+
153
+ def pop(self, name, **kwargs):
154
+ """
155
+ 弹出
156
+
157
+ 参数:
158
+ name: <str> 成员名称
159
+ 名称一定要准确,不能含有模糊的 | 字符
160
+ default: 默认值
161
+ 找不到时,若无默认值则报错,否则将返回默认值
162
+ """
163
+ assert "|" not in name, \
164
+ f'to pop up a specific member needs to give the exact name, ' \
165
+ f'does not support the "|" character with automatic deduction, invalid name: {name}, ' \
166
+ f'what you probably want to pop is {name.replace("|", ":")}'
167
+ res, b_found = None, False
168
+
169
+ def func(_, idx, value):
170
+ nonlocal res, b_found
171
+ if res is None and idx == name:
172
+ res, b_found = value, True
173
+ return True
174
+ else:
175
+ return False
176
+
177
+ traverse(var=self.database, match_cond=func, action_mode="remove", b_use_name_as_idx=True)
178
+ if b_found:
179
+ return res
180
+ else:
181
+ if "default" in kwargs:
182
+ return kwargs["default"]
183
+ else:
184
+ raise AssertionError(f'element {name} not exists')
185
+
186
+ def clear(self):
187
+ self.database.clear()
188
+
189
+ # -------------------- 装饰器 --------------------- #
190
+
191
+ def register(self, name=None, b_force=False):
192
+ """
193
+ 用于注册成员的装饰器
194
+ 成员可以是函数、类或者callable的实例
195
+
196
+ 参数:
197
+ name: <str> 成员名称
198
+ 默认为 None
199
+ b_force: <boolean> 是否强制注册
200
+ 默认为 False
201
+ (以上参数具体参考 add() 函数介绍)
202
+ """
203
+
204
+ def wrapper(obj):
205
+ nonlocal self, name, b_force
206
+ self.add(obj, name=name, b_force=b_force)
207
+ return obj
208
+
209
+ return wrapper
210
+
211
+ # -------------------- 其他 --------------------- #
212
+
213
+ def collect_from(self, path_ls):
214
+ """
215
+ 遍历 path_ls 下的所有模块,并自动导入其中被 register() 装饰器包裹的部分
216
+ 注意,自动导入时使用的 add() 方法中的 b_force 将强制设置为 True
217
+ 这意味着不再检查可能冲突的添加项
218
+ """
219
+ temp = None
220
+ for loader, module_name, is_pkg in pkgutil.walk_packages(path_ls):
221
+ module = loader.find_module(module_name).load_module(module_name)
222
+ if temp is None:
223
+ for name, obj in inspect.getmembers(module):
224
+ if getattr(obj, "name", None) == Registry.name and getattr(obj, "uid") == self.uid:
225
+ temp = obj
226
+ temp.inactivate_b_force_of_add = True
227
+ break
228
+ if temp is not None:
229
+ self.database = temp.database
230
+
231
+
232
+ UNIFIED_REGISTRY = Registry(uid="UNIFIED_REGISTRY")
@@ -2,7 +2,7 @@ import random
2
2
  import torch
3
3
  import numpy as np
4
4
  import copy
5
- from kevin_toolbox.computer_science.algorithm.utils import set_value_by_name, get_value_by_name
5
+ from kevin_toolbox.computer_science.algorithm.for_nested_dict_list import set_value_by_name, get_value_by_name
6
6
 
7
7
 
8
8
  class Strategy_Manager:
@@ -1,4 +0,0 @@
1
- from .get_hash import get_hash
2
- from .traverse import traverse
3
- from .get_value_by_name import get_value_by_name
4
- from .set_value_by_name import set_value_by_name
@@ -2,7 +2,7 @@ import os
2
2
  import json
3
3
  import copy
4
4
  from kevin_toolbox.data_flow.file.json_.converter import integrate
5
- from kevin_toolbox.computer_science.algorithm.utils import traverse
5
+ from kevin_toolbox.computer_science.algorithm.for_nested_dict_list import traverse
6
6
 
7
7
 
8
8
  def write_json(content, file_path, sort_keys=False, converters=None):
@@ -11,7 +11,7 @@ class Singleton_for_uid:
11
11
  def __new__(cls, *args, **kwargs):
12
12
  """
13
13
  __new__函数返回的实例,将作为self参数被传入到__init__函数。
14
- 如果__new__函数返回一个已经存在的实例(不论是哪个类的),__init__不会被调用。
14
+ 如果__new__函数返回一个已经存在的实例(不论是哪个类的),__init__还是会被调用的,所以要特别注意__init__中对变量的赋值。
15
15
  """
16
16
  uid = kwargs.get("uid", None)
17
17
  exist_ok = kwargs.get("exist_ok", True)
@@ -29,6 +29,12 @@ class Singleton_for_uid:
29
29
  return super().__new__(cls)
30
30
 
31
31
  def __init__(self, *args, **kwargs):
32
+ try:
33
+ getattr(self, "uid")
34
+ except :
35
+ pass
36
+ else:
37
+ return
32
38
  uid = kwargs.get("uid", None)
33
39
  assert isinstance(uid, (str, type(None),)), \
34
40
  TypeError(f"uid should be string or None, but get a {type(uid)}!")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kevin-toolbox-dev
3
- Version: 1.0.10b0
3
+ Version: 1.0.12
4
4
  Summary: 一个常用的工具代码包集合
5
5
  Home-page: https://github.com/cantbeblank96/kevin_toolbox
6
6
  Download-URL: https://github.com/username/your-package/archive/refs/tags/v1.0.0.tar.gz
@@ -50,16 +50,15 @@ pip install kevin-toolbox --no-dependencies
50
50
 
51
51
  [版本更新记录](./notes/Release_Record.md):
52
52
 
53
- - v 1.0.10(2023-06-02
54
- - move get_value_by_name() from patches.utils to computer_science.algorithm.utils
55
- - add set_value_by_name() to computer_science.algorithm.utils
56
- - 增加了 computer_science.algorithm.scheduler ,其中包含
57
- - Trigger 触发器
58
- - Strategy_Manager 策略管理器
59
- - 利用这两个类,就可以根据状态来调用对应策略,进而去调整变量中对应的部分。
60
- - v 1.0.10b(2023-06-04)
61
- - kevin_toolbox.data_flow.file
62
- - 让 kevin_notation 中的 column_dict 方式支持单行写入
53
+ - v 1.0.12(2023-06-13
54
+ - computer_science.algorithm.registration
55
+ - 添加了 Registry 注册器类,它具有以下功能:
56
+ - 管理成员,包括添加 add()、获取 get() pop() 成员等
57
+ - 支持通过装饰器 register() 来添加成员
58
+ - 支持通过 collect_from() 搜索指定的路径,当该路径下的模块被 register() 装饰器包裹时,将自动导入(用于解决python中的模块是惰性的问题)
59
+
60
+ - fix bug in kevin_toolbox/developing/design_pattern/singleton/singleton_for_uid.py
61
+ - 即使`__new__`函数返回一个已经存在的实例,`__init__`还是会被调用的,所以要特别注意`__init__`中对变量的赋值,避免对已经存在的实例中的变量重新进行初始化
63
62
 
64
63
 
65
64
 
@@ -1,18 +1,32 @@
1
- kevin_toolbox/__init__.py,sha256=0aIZpky3PEZaFIy-4bugPV_dIRS6SKEeMUEVBjoVMNA,412
1
+ kevin_toolbox/__init__.py,sha256=35QOrp5USStDrcp4L0SIdrSeOKRCZb4IMsfUty8R0rU,411
2
2
  kevin_toolbox/computer_science/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  kevin_toolbox/computer_science/algorithm/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
4
4
  kevin_toolbox/computer_science/algorithm/combinatorial_optimization/__init__.py,sha256=fBMX0_WiV8kfHLWZNfVe2uL67gsN_oHfpbuHaHUOiys,142
5
5
  kevin_toolbox/computer_science/algorithm/combinatorial_optimization/get_subset_with_largest_product.py,sha256=d43k85Jafgu97E37GtPW2zgOY7O6jwAcZlljr4JJZJ4,1832
6
6
  kevin_toolbox/computer_science/algorithm/combinatorial_optimization/zero_one_knapsack_problem.py,sha256=PR-JBphNdGZZvg016Q5iKzU9c44dTbqRFWrOg31EaIY,2819
7
7
  kevin_toolbox/computer_science/algorithm/combinatorial_optimization/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- kevin_toolbox/computer_science/algorithm/combinatorial_optimization/test/test_get_subset_with_largest_product.py,sha256=5nq_YH_w4i6ThNTw6sErI_FcbIgsk92hxM8bNfS2EXg,1920
9
- kevin_toolbox/computer_science/algorithm/combinatorial_optimization/test/test_zero_one_knapsack_problem.py,sha256=SkconcER67bn76gbTfI_M2orqqNVPgcvOV-EY2uHCOY,2084
8
+ kevin_toolbox/computer_science/algorithm/combinatorial_optimization/test/test_get_subset_with_largest_product.py,sha256=MVsQ1KgjwIVrXCejE6T08JOYnyXS2a9YMVBenvi6qXM,1914
9
+ kevin_toolbox/computer_science/algorithm/combinatorial_optimization/test/test_zero_one_knapsack_problem.py,sha256=4j7IBmqkUSRFFIOOMU721eIwaLEiYL2BLx6xN5mJPDQ,2078
10
+ kevin_toolbox/computer_science/algorithm/for_dict/__init__.py,sha256=YFxhbWIsOMGf7ay3fh0sosvXzpuqQQC1bkXK75LAqO4,37
11
+ kevin_toolbox/computer_science/algorithm/for_dict/deep_update.py,sha256=GN5hq5cAorANwSkvgXNyXyAtrQIRzysEtUK_7zjWp9k,767
12
+ kevin_toolbox/computer_science/algorithm/for_nested_dict_list/__init__.py,sha256=4SFdm9TmCJN8-AtUKhMd56XDnXo8qxdZdG_YMc7YPP4,258
13
+ kevin_toolbox/computer_science/algorithm/for_nested_dict_list/count_leaf_node_nums.py,sha256=CY9fXmdkwWqHwP62LyxCp7uqt5OMNcSm1zD4s4Ol_x0,645
14
+ kevin_toolbox/computer_science/algorithm/for_nested_dict_list/get_hash.py,sha256=Ygadnn5dnvIeE-9t39p2EwNKNRLzomL37ZsRD5daXxo,1286
15
+ kevin_toolbox/computer_science/algorithm/for_nested_dict_list/get_leaf_nodes.py,sha256=o1ZIWhmw1_2JGE7Z1TweQx7qb5nXvHtRYbcWd2SMZbI,721
16
+ kevin_toolbox/computer_science/algorithm/for_nested_dict_list/get_value_by_name.py,sha256=rJoDPyAMz5Fs67EbBMOm97QQeJhyP7S4mzUC6BDgk04,1912
17
+ kevin_toolbox/computer_science/algorithm/for_nested_dict_list/set_value_by_name.py,sha256=o3yUS0WmmnS5fC4-e2GCR9BL5mYE_4AuyxCTvYP1wPA,2691
18
+ kevin_toolbox/computer_science/algorithm/for_nested_dict_list/traverse.py,sha256=MJBcyjLhzqsSl3EEKkU2FxrpD7WSLPmGQHLhNqxjbgI,3263
19
+ kevin_toolbox/computer_science/algorithm/for_seq/__init__.py,sha256=qXNVulpOBOWlD2yJ9L4D5bfrNFmnBd29ibtUbvaJHYk,76
20
+ kevin_toolbox/computer_science/algorithm/for_seq/flatten_list.py,sha256=XnDq-_nQln55vwpAnBslyOKI_KYq11C7PmfLChhSe0k,1046
21
+ kevin_toolbox/computer_science/algorithm/for_seq/get_subsets.py,sha256=uVc2pf9cBjX9sWd9VJ3w6nbsRPaeFT1fXRFfGl1zk6Q,309
10
22
  kevin_toolbox/computer_science/algorithm/locks/__init__.py,sha256=ZjZjqGsQB-z9MoYfOPYlI0H7nfZI1hNgxtmJaDdrynI,35
11
23
  kevin_toolbox/computer_science/algorithm/locks/mutex_lock.py,sha256=81cCw3oTXCZxFNhUzFTB5cPKmvbcLM_Gg-5DlT2nuRQ,2492
12
24
  kevin_toolbox/computer_science/algorithm/pareto_front/__init__.py,sha256=LbeaSzG0hkx8NHAlzvEalrGi2WufaXguVfeBRzaw-MA,57
13
25
  kevin_toolbox/computer_science/algorithm/pareto_front/get_pareto_points_idx.py,sha256=a-8Js-dpkuVu9MsImW9hwHp9OTC278xo9oJP96oX0Io,2712
26
+ kevin_toolbox/computer_science/algorithm/registration/__init__.py,sha256=teEd9HkrB6baLpwNwae5c4wn0QRwV3KtBv-2V9-Z7cc,49
27
+ kevin_toolbox/computer_science/algorithm/registration/registry.py,sha256=XPZjWNBe2hpPqf4E8FBC9c5poqXzhrJEuIG4Vf1UQWU,10160
14
28
  kevin_toolbox/computer_science/algorithm/scheduler/__init__.py,sha256=ENzZsNaMu6ISilTxeE3_EP_L0dNi8SI7IYdTdxic2nw,76
15
- kevin_toolbox/computer_science/algorithm/scheduler/strategy_manager.py,sha256=IuZRnzGGq5i5zQKRwEUW_SJpuEBT9GTC3KvIlwqoe7o,11480
29
+ kevin_toolbox/computer_science/algorithm/scheduler/strategy_manager.py,sha256=yVOLk_k-V_RN7GMTx2-fL4eXbHa-DQDnIbmbpvGamyc,11495
16
30
  kevin_toolbox/computer_science/algorithm/scheduler/trigger.py,sha256=-WN7tZiXzFdxoB3aikwdhUmM49dpq334AGem4EL7Dpc,1227
17
31
  kevin_toolbox/computer_science/algorithm/search/__init__.py,sha256=zja7FXLTNd2dSVzzGp1TbBp4i3TDY8S9tcJ9pqc684A,41
18
32
  kevin_toolbox/computer_science/algorithm/search/binary_search.py,sha256=FcOdgxfuNews_AhPF_CoQDr2vBPqpUpifF7Fmgml1p4,1013
@@ -20,16 +34,7 @@ kevin_toolbox/computer_science/algorithm/statistician/__init__.py,sha256=zW1zesX
20
34
  kevin_toolbox/computer_science/algorithm/statistician/_init_var.py,sha256=-u9RFiiPFlCLwdVfVZslYq9jNyDz4r_A9kRSH05sExw,904
21
35
  kevin_toolbox/computer_science/algorithm/statistician/average_accumulator.py,sha256=hdgpnMtvBQri-_ZxEAkSwyK6_qy4sJdqEeYauOBgLMI,3101
22
36
  kevin_toolbox/computer_science/algorithm/statistician/exponential_moving_average.py,sha256=P5E1EL1ioRAz_vlI-Ls9gZFhxVA83eTNjUppb2WqdlM,5571
23
- kevin_toolbox/computer_science/algorithm/utils/__init__.py,sha256=ouMtbSAIEiiLTyvu80GJHkTbE3CPS-fE5-hH_QCdhVs,160
24
- kevin_toolbox/computer_science/algorithm/utils/get_hash.py,sha256=Ygadnn5dnvIeE-9t39p2EwNKNRLzomL37ZsRD5daXxo,1286
25
- kevin_toolbox/computer_science/algorithm/utils/get_value_by_name.py,sha256=oOCjEwAtCU64AH9hRjP8C15YOaSt07080JarI262-gM,2100
26
- kevin_toolbox/computer_science/algorithm/utils/set_value_by_name.py,sha256=KWAnNI_xfj-khJjxDFUVNL_I1HVz_zbY56VLWiaNIDE,2217
27
- kevin_toolbox/computer_science/algorithm/utils/traverse.py,sha256=Eumb3CfNZ1FRaHk9r-hkJWwW0h2oTEizgOhMNOFnezE,2603
28
- kevin_toolbox/computer_science/algorithm/utils/for_dict/__init__.py,sha256=YFxhbWIsOMGf7ay3fh0sosvXzpuqQQC1bkXK75LAqO4,37
29
- kevin_toolbox/computer_science/algorithm/utils/for_dict/deep_update.py,sha256=GN5hq5cAorANwSkvgXNyXyAtrQIRzysEtUK_7zjWp9k,767
30
- kevin_toolbox/computer_science/algorithm/utils/for_seq/__init__.py,sha256=qXNVulpOBOWlD2yJ9L4D5bfrNFmnBd29ibtUbvaJHYk,76
31
- kevin_toolbox/computer_science/algorithm/utils/for_seq/flatten_list.py,sha256=XnDq-_nQln55vwpAnBslyOKI_KYq11C7PmfLChhSe0k,1046
32
- kevin_toolbox/computer_science/algorithm/utils/for_seq/get_subsets.py,sha256=uVc2pf9cBjX9sWd9VJ3w6nbsRPaeFT1fXRFfGl1zk6Q,309
37
+ kevin_toolbox/computer_science/algorithm/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
38
  kevin_toolbox/computer_science/data_structure/__init__.py,sha256=_esL73v9Gi40xb5N7UGxslIk8yHM6idQlXbzELR7XhA,31
34
39
  kevin_toolbox/computer_science/data_structure/executor.py,sha256=i-2zQj4lj597BvkarCMT-gYxhoRe8cHyQyO98X7m-9E,6206
35
40
  kevin_toolbox/dangerous/__init__.py,sha256=7TqcyVO0IUUZnFw6vFybvdY7UCg-Bv1Moh95IIVMT2c,93
@@ -45,7 +50,7 @@ kevin_toolbox/data_flow/core/reader/unified_reader_base.py,sha256=P7uqkjfHwc_KHU
45
50
  kevin_toolbox/data_flow/file/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
46
51
  kevin_toolbox/data_flow/file/json_/__init__.py,sha256=VAt8COS2tO3PJRuhSc43i35fEOlArFM_YahdTmEBaHE,85
47
52
  kevin_toolbox/data_flow/file/json_/read_json.py,sha256=9UcFvC-4ZfoTlQPoEke0NEMS19lbbRPbErHvJt4-04g,237
48
- kevin_toolbox/data_flow/file/json_/write_json.py,sha256=l2H3pBUIbcAlxSAUc3hJyb5IlgTO1evJlWhrkxclGK4,770
53
+ kevin_toolbox/data_flow/file/json_/write_json.py,sha256=y1H3wuwOpdMbJuy1NOKRXv5HzVeTtsDdOYqIqsQgOJc,785
49
54
  kevin_toolbox/data_flow/file/json_/converter/__init__.py,sha256=gF6eH6G4ndr4fi1qBZAKZ8VDZ6lhNz2w06YmE6yxoN4,161
50
55
  kevin_toolbox/data_flow/file/json_/converter/convert_dict_key_to_number.py,sha256=SuSZj_HCqKZutHAJ5AttABnGBRZplPGQhMxJBt2Wlgc,559
51
56
  kevin_toolbox/data_flow/file/json_/converter/convert_ndarray_to_list.py,sha256=GALpC1MFJ4aMzs0FZIfJScYznfCP-gmhPeM8sWXGSWg,391
@@ -76,7 +81,7 @@ kevin_toolbox/developing/design_pattern/producer_consumer/node.py,sha256=Q2zzboN
76
81
  kevin_toolbox/developing/design_pattern/producer_consumer/producer.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
82
  kevin_toolbox/developing/design_pattern/producer_consumer/sender.py,sha256=sn5WkJS3VS-nYbOO9emB8MMfGYHUKM6voj94KM2QIHs,51
78
83
  kevin_toolbox/developing/design_pattern/singleton/__init__.py,sha256=2PYWz9DDkR7a6vYb_4i3qzBsoskubozMwVf7IGUOz6M,49
79
- kevin_toolbox/developing/design_pattern/singleton/singleton_for_uid.py,sha256=Vu5_WdCNemBwZYFacfxZOq42DveQy41aL-8SCuaWid4,3631
84
+ kevin_toolbox/developing/design_pattern/singleton/singleton_for_uid.py,sha256=AlerlDTfa0ZN3XiV5YmTI_OKR_F3RyeNuafYdHwCvfo,3803
80
85
  kevin_toolbox/developing/numerical_characteristics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
86
  kevin_toolbox/developing/numerical_characteristics/iou.py,sha256=XfN8LN3IY9C5HqbXi4XPnp1JX6K8_7-_rAjC-nVB-NI,2953
82
87
  kevin_toolbox/developing/temperate/__init__.py,sha256=9OdEkRFxCOtAf_QRUeNo6tH3t2cPGH_aLLl7lypK24s,630
@@ -209,7 +214,7 @@ kevin_toolbox/patches/for_torch/math/get_y_at_x.py,sha256=bfoVcasZ_tMdhR_1Me0Jli
209
214
  kevin_toolbox/patches/for_torch/math/my_around.py,sha256=ptpU3ids50gwf663EpHbw7raj9tNrDGBFZ5t_uMNH14,1378
210
215
  kevin_toolbox/patches/for_torch/nn/__init__.py,sha256=aJs3RMqRzQmd8KKDmQW9FxwCqS5yfPqEdg-m0PwlQro,39
211
216
  kevin_toolbox/patches/for_torch/nn/lambda_layer.py,sha256=KUuLiX_Dr4bvRmpAaCW5QTDWDcnMPRnw0jg4NNXTFhM,223
212
- kevin_toolbox_dev-1.0.10b0.dist-info/METADATA,sha256=JR9QGcUzyd-0Rx4Yx-ZnwFGtAOSv0fFLL5mQJe92osc,1816
213
- kevin_toolbox_dev-1.0.10b0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
214
- kevin_toolbox_dev-1.0.10b0.dist-info/top_level.txt,sha256=S5TeRGF-PwlhsaUEPTI-f2vWrpLmh3axpyI6v-Fi75o,14
215
- kevin_toolbox_dev-1.0.10b0.dist-info/RECORD,,
217
+ kevin_toolbox_dev-1.0.12.dist-info/METADATA,sha256=rwvX_e0lCFW1j4G7PPSy3NT9wH6HbJQhXm-zGDyP7pE,2023
218
+ kevin_toolbox_dev-1.0.12.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
219
+ kevin_toolbox_dev-1.0.12.dist-info/top_level.txt,sha256=S5TeRGF-PwlhsaUEPTI-f2vWrpLmh3axpyI6v-Fi75o,14
220
+ kevin_toolbox_dev-1.0.12.dist-info/RECORD,,