-2

I define my class like this:

class Simple():
    def __init__(self):
        self.string = "Hello World"

    def __enter__(self):
        pass

    def __exit__(self):
        pass

and call it like this:

with Simple() as simple_test:
    print(simple_test.string)

I get the following error:

    print(simple_test.string)
AttributeError: 'NoneType' object has no attribute 'string'

Why is my class None?

Gabio
  • 9,126
  • 3
  • 12
  • 32
ckemere
  • 59
  • 6

2 Answers2

1

The __enter__ method must return self:

def __enter__(self):
    return self
Gabio
  • 9,126
  • 3
  • 12
  • 32
  • I think there's also an error in the __exit__() specification? – ckemere Mar 31 '20 at 20:09
  • The `__exit__` method should only do the cleanup. It doesn't return anything... – Gabio Mar 31 '20 at 20:12
  • My (finally realized) understanding is that it should be `__exit__(self, exc_type, exc_value, exc_traceback)`? – ckemere Apr 01 '20 at 20:11
  • Yes, if you gonna use it inside your `__exit__`, you can. If you just want to `pass` it, and you added `__exit__` it just to implement context manager, you can leave the `__exit__` func without params (only self) – Gabio Apr 01 '20 at 21:08
  • By the way, if it helped you, please accept the answer in order to help other people struggling with similar issue. – Gabio Apr 01 '20 at 21:12
0

__enter__ should return whatever you want to bind in the as clause, see python docs.

Because your __enter__ doesn't return anything, the value bound to simple_test is None.

I think you want this:

class Simple():
    def __init__(self):
        self.string = "Hello World"

    def __enter__(self):
        return self

    def __exit__(self):
        pass
Subhaneil Lahiri
  • 408
  • 3
  • 10