Reputation: 1605
In Python, I know it's possible to say something like
>>> class C:
... def __setattr__(self, name, value):
... print("Hey, you can't set {0} to {1}!".format(name, value))
...
>>> x = C()
>>> x.y = 5
Hey, you can't set y to 5!
But the following still works:
>>> C.y = 5
>>> print(C.y)
5
Is it possible to get functionality like:
>>> C.y = 5
Hey, you can't set y to 5!
Asking solely out of curiosity, as I can't really think of an example where that'd be genuinely practical.
Upvotes: 5
Views: 1416
Reputation: 1121894
Like all special methods, __setattr__
is accessed on the type; for instances that is the class, for classes, that is the metaclass.
You'll have to define it on a custom metaclass instead of directly on the class itself:
class SetAttrMeta(type):
def __setattr__(cls, name, value):
print("Hey, you can't set {0} to {1}!".format(name, value))
class C(metaclass=SetAttrMeta):
pass
Python then looks up __setattr__
on the return value of type(C)
, which here is SetAttrMeta
.
Demo:
>>> class SetAttrMeta(type):
... def __setattr__(cls, name, value):
... print("Hey, you can't set {0} to {1}!".format(name, value))
...
>>> class C(metaclass=SetAttrMeta):
... pass
...
>>> C.spam = 'eggs'
Hey, you can't set spam to eggs!
Upvotes: 10