Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global state in Python module

I am writing a Python wrapper for a C library using the cffi.

The C library has to be initialized and shut down. Also, the cffi needs some place to save the state returned from ffi.dlopen().

I can see two paths here:

Either I wrap this whole stateful business in a class like this

class wrapper(object):
    def __init__(self):
        self.c = ffi.dlopen("mylibrary")
        self.c.initialize()
    def __del__(self):
        self.c.terminate()

Or I provide two global functions that hide the state in a global variable

def initialize():
    global __library 
    __library = ffi.dlopen("mylibrary")
    __library.initialize()
def terminate():
    __library.terminate()
    del __library

The first path is somewhat cumbersome in that it requires the user to always create an object that really serves no other purpose other than managing the library state. On the other hand, it makes sure that terminate() is actually called every time.

The second path seems to result in a somewhat easier API. However, it exposes some hidden global state, which might be a bad thing. Also, if the user forgets to call terminate(), the C library is not unloaded correctly (which is not a big problem on the C side).

Which one of these paths would be more pythonic?

like image 245
bastibe Avatar asked Jun 27 '13 14:06

bastibe


People also ask

What is global state in Python?

What Is the Global Variable In Python? In the programming world, a global variable in Python means having a scope throughout the program, i.e., a global variable value is accessible throughout the program unless shadowed. A global variable in Python is often declared as the top of the program.

What is global module in Python?

A global variable is a variable which is accessible in multiple scopes. In Python, it is better to use a single module to hold all the global variables you want to use and whenever you want to use them, just import this module, and then you can modify that and it will be visible in other modules that do the same.

What does global () do in Python?

In Python, global keyword allows you to modify the variable outside of the current scope. It is used to create a global variable and make changes to the variable in a local context.

What are the global variables across modules in Python?

Each Module/file has its own global variable When you create a variable (not within a function) in a Python file, you mount this variable to the namespace of the current module. Every command in this Python file can access, read, and modify the value of the variable, that is, it becomes a global variable.


1 Answers

Exposing a wrapper object only makes sense in python if the library actually supports something like multiple instances in one application. If it doesn't support that or it's not really relevant go for kindall's suggestion and just initialize the library when imported and add an atexit handler for cleanup.

Adding wrappers around a stateless api or even an api without support for keeping different sets of state is not really pythonic and would raise expectations that different instances have some kind of isolation.

Example code:

import atexit

# Normal library initialization
__library = ffi.dlopen("mylibrary")
__library.initialize()

# Private library cleanup function
def __terminate():
    __library.terminate()
# register function to be called on clean interpreter termination
atexit.register(__terminate)

For more details about atexit this question has some more details, as has the python documentation of course.

like image 88
textshell Avatar answered Sep 18 '22 03:09

textshell