Purely curiosity question:
class Li(list): pass
m, n= Li([1]), Li([2])
def r(*args, **kwargs): raise Exception('hop')
setattr(m, '__iadd__', r)
m += n
print m # [1, 2]
setattr(Li, '__iadd__', r)
m += n
Output:
[1, 2]
Traceback (most recent call last):
File "C:\...\test_override.py", line 8, in <module>
m+=n
File "C:\...\test_override.py", line 3, in r
def r(*args, **kwargs): raise Exception('hop')
Exception: hop
If I use setattr(m, 'append', r)
then m.append(2)
will fail. So is __iadd__
called on the class object ?
Also can I use settattr
from class scope ? A naive attempt as in:
def r(*args, **kwargs): raise Exception('hop')
class Li(list):
for s in {'__iadd__','append'}: setattr(Li, s, r)
fails with NameError: name 'Li' is not defined
In new style classes, the instance
__getattr__
method no longer intercepts calls made by built-in operations. When the built-in operation is used, the search begins at the class level instead of at the instance level. Nevertheless, an explicit call to the method name will work:One way to accomplish your second goal is to use a metaclass, especially if you only want to create the attributes once (as per your comments):