gpt4 book ai didi

python : Argument based Singleton

转载 作者:行者123 更新时间:2023-12-05 07:48:01 25 4
gpt4 key购买 nike

我正在关注这个 link并尝试创建一个单例类。但是,将参数(在启动类时传递)考虑在内,以便在参数相同时返回相同的对象。

因此,我不想将类名/类引用存储为 dict 键,而是想将传递的参数作为键存储在 dict 中。但是,也可能存在不可散列的参数(例如 dictset 本身)。

存储类参数和类对象映射的最佳方式是什么?这样我就可以返回一个与参数对应的对象。

还是谢谢你


编辑-1:多一点解释。假设有如下类

class A:
__metaclass__ == Singleton
def __init__(arg1, arg2):
pass

现在,A(1,2) 应该始终返回相同的对象。但是,它应该不同于 A(3,4)

我认为,参数在很大程度上定义了一个类的功能。假设该类是否要建立 redis 连接。我可能想用 diff redis hosts 作为参数创建 2 个单例对象,但底层类/代码可能是通用的。

最佳答案

正如 theheadofabroom 和我已经在评论中提到的那样,依赖不可散列值(例如缓存或内存)时存在一些可能性。因此,如果您仍然想这样做,下面的示例不会在 __new____init__ 方法中隐藏内存。 (自内存类会很危险,因为内存标准可能会被您无法控制的代码所愚弄)。

相反,我提供了函数 memoize,它返回一个类的内存工厂函数。由于没有通用的方法来区分不可散列的参数,如果它们将导致一个实例等同于一个已经存在的实例,则必须明确提供内存语义。这是通过将 keyfunc 函数传递给 memoize 来实现的。 keyfunc 采用与类的 __init__ 方法相同的参数并返回一个可哈希键,其相等关系 (__eq__) 决定内存。

memoization 的正确使用是使用代码的责任(提供合理的 keyfunc 和使用工厂),因为要 memoization 的类没有被修改并且仍然可以正常实例化.

def memoize(cls, keyfunc):
memoized_instances = {}

def factory(*args, **kwargs):
key = keyfunc(*args, **kwargs)
if key in memoized_instances:
return memoized_instances[key]

instance = cls(*args, **kwargs)
memoized_instances[key] = instance
return instance

return factory


class MemoTest1(object):
def __init__(self, value):
self.value = value

factory1 = memoize(MemoTest1, lambda value : value)

class MemoTest2(MemoTest1):
def __init__(self, value, foo):
MemoTest1.__init__(self, value)
self.foo = foo

factory2 = memoize(MemoTest2, lambda value, foo : (value, frozenset(foo)))

m11 = factory1('test')
m12 = factory1('test')
assert m11 is m12

m21 = factory2('test', [1, 2])

lst = [1, 2]
m22 = factory2('test', lst)

lst.append(3)
m23 = factory2('test', lst)

assert m21 is m22
assert m21 is not m23

我只将 MemoTest2 作为 MemoTest1 的子类包括在内,以表明使用常规类继承没有魔法。

关于 python : Argument based Singleton,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39033946/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com