Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

designing python api. reliable cleanup vs easy-to-use in interpreter

I'm working on a design of the python-based API. At the moment I've met an issue with two divergent requirements. On the one side I would like to provide reliable way to cleanup API-related resources. Thus as I know the best way to do it is to use context managers like:

# lib

class Client(object):
  def __enter__(self):
    return self

  def __exit__(self, exc_type, exc_val, tb):
    do_cleanup()

  def method1(self):
    pass

  def method2(self):
    pass

# api user
import mylib

with mylib.Client() as client:
  client.method1()
  client.method2()

On the other hand I would like to provide a way to seamlessly use my lib in interactive interpreter. But using compound construct like with or try-except-finally in interpreter makes usage of interpreter not so groovy because with-block is treated as a single statement. And it's would be preferred to use single statement per single api method like:

# interpreter session

>>> import mylib
>>> client = mylib.Client()
<client object at ...>
>>> client.method1()
True
>>> client.method2()
100

So, could I have any options here? Definitely there is a way to provide different usage semantics for scripts and for interpreter, but I would like to use it as a last resort.

like image 575
reddot Avatar asked Nov 26 '25 17:11

reddot


1 Answers

The typical way to do this is to provide a method to do the cleanup manually, and have __exit__ call that method. For your example, if do_cleanup was implemented as a method, it can just be called from the interpreter when done with it.

class Client(object):
  def __enter__(self):
    return self

  def __exit__(self, exc_type, exc_val, tb):
    self.do_cleanup()

  def do_cleanup(self):
    pass

  def method1(self):
    pass

  def method2(self):
    pass

Then, in the interpreter:

>>> import mylib
>>> client = mylib.Client()
<client object at ...>
>>> client.method1()
True
>>> client.method2()
100
>>> client.do_cleanup()

I would recommend renaming do_cleanup to close or similar, so that the similarity between File Objects is more obvious.

like image 185
ford Avatar answered Nov 29 '25 09:11

ford