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

kuz*_*roo 1 python class instance class-method

我希望能够使用__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"
Run Code Online (Sandbox Code Playgroud)

che*_*ner 8

当你编写时del obj[key],Python会调用__delitem__类的方法obj,而不是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)
Run Code Online (Sandbox Code Playgroud)

改变的元类FootypeClassMapping提供Foo

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

  • 与任何方法一样,函数与类绑定,而不是与对象绑定,对象是函数的隐式第一个参数.试图使`__delitem__`成为一个类方法而不是常规实例方法将是一个特殊情况,Python根本没有实现. (2认同)