Skip to main content
 首页 » 编程设计

python之在 Python 中将 __delitem__ 与类对象而不是实例一起使用

2025年05月04日16lvdongjie

我希望能够将 __delitem__ 与类级变量一起使用。 我的用例可以找到here (使用 _reg_funcs 的答案)但它基本上涉及一个装饰器类,用于保存它所装饰的所有函数的列表。有没有办法让类对象支持 __delitem__?我知道我可以为此目的专门保留一个实例,但我宁愿不必这样做。

class Foo(object): 
    _instances = {} 
 
    def __init__(self, my_str): 
        n = len(self._instances) + 1 
        self._instances[my_str] = n 
        print "Now up to {} instances".format(n) 
 
    @classmethod 
    def __delitem__(cls, my_str): 
        del cls._instances[my_str] 
 
 
abcd = Foo('abcd') 
defg = Foo('defg') 
 
print "Deleting via instance..." 
del abcd['abcd'] 
print "Done!\n" 
 
print "Deleting via class object..." 
del Foo['defg'] 
print "You'll never get here because of a TypeError: 'type' object does not support item deletion" 

请您参考如下方法:

当你写del obj[key]时,Python调用obj类的__delitem__方法,而不是obj 。所以 del obj[key] 结果为 type(obj).__delitem__(obj, key)。

在您的例子中,这意味着 type(Foo).__delitem__(Foo, 'abcd')。 type(Foo) 为type,type.__delitem__ 未定义。您不能修改 type 本身,您需要将 Foo 本身的类型更改为可以修改的类型。

您可以通过定义一个新的 元类 来做到这一点,它只是 type 的子类,然后指示 Python 使用您的新元类来创建 Foo 类(不是 Foo 的实例,而是 Foo 本身)。

class ClassMapping(type): 
    def __new__(cls, name, bases, dct): 
        t = type.__new__(cls, name, bases, dct) 
        t._instances = {} 
        return t 
    def __delitem__(cls, my_str): 
        del cls._instances[my_str] 
 
class Foo(object): 
    __metaclass__ = ClassMapping 
    def __init__(self, my_str): 
        n = len(Foo._instances) + 1 
        Foo._instances[my_str] = n 
        print "Now up to {} instances".format(n) 

将 Foo 的元类从 type 更改为 ClassMapping 为 Foo 提供

  1. 引用字典的类变量_instances
  2. 一个 __delitem__ 方法,它从 _instances 中删除参数。