繁体   English   中英

在类对象而不是Python实例中使用__delitem__

[英]Using __delitem__ with a class object rather than an instance in Python

我希望能够将__delitem__与类级变量一起使用。 我的用例可以在这里找到(使用_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类而不是obj类的__delitem__方法。 所以del obj[key]结果是type(obj).__delitem__(obj, key)

在您的情况下,这意味着type(Foo).__delitem__(Foo, 'abcd') type(Foo)type ,没有定义type.__delitem__ 您不能自行修改type ,而需要将Foo本身的类型更改为可以的类型。

为此,您需要定义一个新的metaclass ,它只是type的子type ,然后指示Python使用新的metaclass创建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更改为ClassMappingFoo提供了

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM