2014-09-04 43 views
4

考慮下面的例子如何限制對象創建

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

這將實際創建9999個按鍵。 – 2014-09-04 11:25:38

+0

爲什麼要限制對象的數量? – 2014-11-09 12:56:03

回答

7

您可以控制如何,或有多少對象通過給你的類創建一個__new__ method

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__()被調用來創建一個新的實例;在這裏我記錄了創建的數量,如果數量太多,會引發異常。您還可以在字典中保留一個實例池,或者以其他方式控制創建新實例。

請注意,這隻適用於new-style classes,繼承object

+0

是否需要一些與併發有關的預防措施? – bereal 2014-09-04 13:55:10

+1

@ bereal:這段代碼不是線程安全的,沒有。這不是重點,重點是說明如何掛鉤實例創建。 – 2014-09-04 14:03:23

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 

您可以選擇一個隨機元素或選擇它存儲的指數的基礎上。在這種方法中,根據你的意圖,你的循環不會失敗,並有可能是正確的異常。