如何限制对象创建

4 投票
2 回答
1696 浏览
提问于 2025-04-19 19:13

考虑下面这个例子

class Key:
    def __init__(self, s):
        self.s = s

d = {}

for x in range(1, 10000):
    t = Key(x)
    d[t] = x

这个代码会创建10000个键。我们能不能控制一下这个键的创建,比如说不让它创建超过5个键的对象?而且循环的部分不能改动。

2 个回答

0

你也可以使用元类的方法。

import weakref
import random

class FiveElementType(type):
    def __init__(self, name, bases, d):
        super(FiveElementType, self).__init__(name, bases, d)
        self.__cache = weakref.WeakValueDictionary()

    def __call__(self, *args):
       if len(self.__cache) == 5:
           return random.choice(self.__cache.values())
       else:
           obj = super(FiveElementType, self).__call__(*args)
           self.__cache[len(self.__cache)] = obj
           return obj

class Key(object):
    __metaclass__ = FiveElementType
    def __init__(self, s):
       self.s = s

你可以随机选择一个元素,或者根据存储的索引来选择。在这种方法中,你的循环不会因为出现异常而失败,这个异常可能是对的,也可能是错的,具体要看你的意图。

7

你可以通过给你的类添加一个 __new__ 方法 来控制创建对象的方式和数量:

class Key(object):
    _count = 0

    def __new__(cls, s):
        if cls._count == 5:
            raise TypeError('Too many keys created')

        cls._count += 1
        return super(Key, cls).__new__(cls, s)

    def __init__(self,s):
        self.s = s

Key.__new__() 这个方法会被调用来创建一个新的实例;在这里,我会记录创建了多少个实例,如果数量太多,就会抛出一个异常。你也可以在字典里保存一组实例,或者用其他方式来控制新实例的创建。

需要注意的是,这个方法只适用于 新式类,也就是那些继承自 object 的类。

撰写回答