I've got a class, where a method should only run once. Of course, it could easily be done with artificial has_executed = True/False
flag, but why use it, if you can just delete the method itself? python
's a duck-typed language, everything is a reference, bla-bla-bla, what can go wrong?
At least it was the thought. I couldn't actually do it:
class A:
def b(self):
print("empty")
self.__delattr__('b')
a = A()
a.b()
raises AttributeError: b
. However, executing self.__getattribute__('b')
returns <bound method A.b of <__main__.A object at 0x000001CDC6742FD0>>
, which sounds stupid to me: why is a method
any different from an attribute
, since everything in python
is just a reference to an object? And why can I __getattribute__
, but not __delattr__
?
The same goes to redefinition. I can easily set any attribute, but methods are a no-no?
class A:
def b(self):
print("first")
self.__setattr__('b', lambda self: print(f"second"))
a = A()
a.b()
a.b()
results into TypeError: <lambda>() missing 1 required positional argument: 'self'
. Which, of course, means, that now python
isn't using dot-notation as intended. Of course, we could ditch the self
attribute in the lambda altogether, considering we've got the reference to it already in b
. But isn't it incorrect by design?
The further I'm trying to take python
to the limit, the more frustrated I become. Some imposed limitations (or seemingly imposed?) seem so unnatural, considering the way the language is marketed. Shouldn't it allow this? Why doesn't it work?
UPD
Ok, consider this:
class A:
def __init__(self):
self.variable = 1
def b(self):
print("old")
self.variable += 1
def new_b():
print("new")
self.variable += 15
self.__setattr__('b', new_b)
It will work and do what we want: none of other objects will have their A.b
method redefined once one object kind of overlays its b
definition. (overlays, since everyone so far says that you cannot redefine a method for an object, but instead only kind of hide it from the caller behind another attribute with the same name, as far as I understand).
Is this good?
__setattr__
instead ofself.b = ...
. But what if you actually want to useself
in the redefined method? Do you just casually reference it from the oldb
's scope? I updated the question. – Deltadeltaic