How to delete property?

Question:

class C():
    @property
    def x(self):
        return 0
delattr(C(), 'x')
>>> AttributeError: can't delete attribute

I’m aware del C.x works, but this deletes the class‘s property; can a class instance‘s property be deleted?

Asked By: OverLordGoldDragon

||

Answers:

I’m aware del C.x works, but this deletes the class’s property; can a class instance’s property be deleted?

There’s no such thing. Properties are defined on the class, there is nothing on the instance in the example you provide. It’s like a method, a method is an attribute of the class which Python execute in the context of the instance.

Answered By: Masklinn

Refer to this answer; TL;DR, it’s not about properties, but bound attributes, and x is bound to the class, not the instance, so it cannot be deleted from an instance when an instance doesn’t have it in the first place. Demo:

class C():
    pass

@property
def y(self):
    return 1

c = C()
c.y = y
del c.y  # works
c.y
>>> AttributeError: 'C' object has no attribute 'y'
Answered By: OverLordGoldDragon

You can do something like this to delete attr from instance.

https://stackoverflow.com/a/36931502/12789671

class C:
    def __init__(self):
        self._x: int = 0
    @property
    def x(self):
        return self._x
    @x.deleter
    def x(self):
        delattr(self, "_x")

obj = C()
delattr(obj, "x")
try:
    print(obj.x)
except AttributeError:
    print("failed to print x")

print(C().x)
failed to print x
0
Answered By: MeatBoyKun95

I got the same error below:

AttributeError: can’t delete attribute

When trying to delete the instance variable name with del as shwon below:

class Person:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name

obj = Person("John")

print(hasattr(obj, "name"))

del obj.name # Here

print(hasattr(obj, "name"))

So, I added @name.deleter method as shown below:

class Person:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name

    @name.deleter # Here
    def name(self):
        del self._name

obj = Person("John")

print(hasattr(obj, "name"))

del obj.name # Here

print(hasattr(obj, "name"))

Then, I could delete the instance variable name with del as shown below:

True
False
Answered By: Kai – Kazuya Ito