Python:基于参数的单例 [英] Python : Argument based Singleton

查看:38
本文介绍了Python:基于参数的单例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm following this link and trying to make a singleton class. But, taking arguments (passed while initiating a class) into account so that the same object is returned if the arguments are same.

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

So, instead of storing class name/class reference as a dict key, I want to store passed arguments as keys in dict. But, there could be unhashable arguments also (like dict, set itself).

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

What is the best way to store class arguments and class objects mapping? So that I can return an object corresponding to the arguments.

还是谢谢.

EDIT-1:多一点解释.假设有如下类

EDIT-1 : A little more explanation. Let's say there is class as follows

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

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

Now, A(1,2) should always return the same object. But, it should be different from A(3,4)

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

I think, the arguments very much define the functioning of a class. Let's say if the class is to make redis connections. I might want to create 2 singletons objects with diff redis hosts as parameters, but the underlying class/code could be common.

推荐答案

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

As theheadofabroom and me already mentioned in the comments, there are some odds when relying on non-hashable values for instance caching or memoization. Therefore, if you still want to do exactly that, the following example does not hide the memoization in the __new__ or __init__ method. (A self-memoizing class would be hazardous because the memoization criterion can be fooled by code that you don't control).

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

Instead, I provide the function memoize which returns a memoizing factory function for a class. Since there is no generic way to tell from non-hashable arguments, if they will result in an instance that is equivalent to an already existing isntance, the memoization semantics have to be provided explicitly. This is achieved by passing the keyfunc function to memoize. keyfunc takes the same arguments as the class' __init__ method and returns a hashable key, whose equality relation (__eq__) determines memoization.

memoization 的正确使用由使用代码负责(提供合理的keyfunc 并使用工厂),因为待记忆的类没有被修改,仍然可以正常实例化.

The proper use of the memoization is in the responsibility of the using code (providing a sensible keyfunc and using the factory), since the class to be memoized is not modified and can still be instantiated normally.

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 的子类,以表明使用常规类继承没有任何魔法.

I only included MemoTest2 as a sublclass of MemoTest1 to show that there is no magic involved in using regular class inheritance.

这篇关于Python:基于参数的单例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆