Make function of class unusable after usage

Advertisements

I want to create a one time usage method in my class. It should be possible to call the function one time, use a variable of the class, remove the variable and also remove the function. If the method is called afterwards it should raise an error that this method does not exist. If created a workaround which kind of achieves what I want, but the traceback is still not perfect, since the method still exists but raises the correct error.

class MyClass:
    def __init__(self):
        self.a = 1
    def foo(self):
        if hasattr(self, 'a'):
            delattr(self, 'a')
        else:
            raise AttributeError('foo')

This gives

Test = MyClass()
Test.foo()
Test.foo()

output:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/Users/path in <cell line: 3>()
      1 Test = MyClass()
      2 Test.foo()
----> 3 Test.foo()

/Users/path in MyClass.foo(self)
      6     delattr(self, 'a')
      7 else:
----> 8     raise AttributeError('foo')

AttributeError: foo

This is the closest I got.

Edit:

Use cas:
The use case for this is a bit complicated, since it is completly out of context. But the idea is that I initialize a lot of these classes and need a one time read out of some information directly afterwards.
More specific, the class is splitting data in a specific way via the __getitem__ method which is most efficient. But I still need the full index list used, which should be the output of the one time function.

I know this is not necessary, I could just never use the method again and everything is fine, but it feels odd having a method that is actually not working anymore. So I am just interested if this is somewhat possible.

>Solution :

I don’t fully understand your use case, but if I were a developer who is using MyClass, I’d be really unhappy to receive AttributeError on the second call of foo. And I’ll be really happy to get a self-explanatory error:

class MyClass:
    def __init__(self):
        self._called = False
    def foo(self):
        if self._called:
            raise Exception('foo can be called only once')
        self._called = True
        # the logic

So here is the solution to your exact question (wouldn’t recommend it):

class MyClass:
    def __init__(self):
        def foo():
            # logic
            print('fooing')
            del self.foo
        self.foo = foo
>>> t1 = MyClass()
>>> t2 = MyClass()
>>> t1.foo()
fooing
>>> t1.foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'foo'
>>> t2.foo()
fooing
>>> t2.foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'foo'

Leave a ReplyCancel reply