¿Cómo se implementan las variables globales de C / C ++ en python?

Mientras leía la documentación de SWIG, pasé por estas líneas …

Las variables globales de C / C ++ son totalmente compatibles con SWIG. Sin embargo, el mecanismo subyacente es algo diferente de lo que podría esperar debido a la forma en que funciona la asignación de Python. Cuando escribes lo siguiente en Python
a = 3.4
“a” se convierte en un nombre para un objeto que contiene el valor 3.4. Si luego escribes
b = a
entonces “a” y “b” son ambos nombres para el objeto que contiene el valor 3.4. Por lo tanto, solo hay un objeto que contiene 3.4 y “a” y “b” son nombres que se refieren a él. Esto es muy diferente de C, donde un nombre de variable se refiere a una ubicación de memoria en la que se almacena un valor (y la asignación copia los datos en esa ubicación). Debido a esto, no hay una forma directa de asignar la asignación de variables en C a la asignación de variables en Python.
Para proporcionar acceso a las variables globales de C, SWIG crea un objeto especial llamado `cvar ‘que se agrega a cada módulo generado por SWIG. Las variables globales son accedidas como atributos de este objeto.

Mi pregunta es cuál es la necesidad de implementar de la manera anterior. Aunque implementamos de la manera mencionada anteriormente, los atributos de objeto también se implementan como objetos.

Por favor, vea el siguiente fragmento de código de Python

a = 10 b = aa is b True class sample: pass obj = sample() obj.a = 10 obj.b = obj.a obj.a is obj.b True 

Aquí, en los dos casos anteriores, la asignación de objetos ocurre de la misma manera.

Se trata del hecho de que SWIG tiene que proporcionar una interfaz a una biblioteca en C / C ++ que actúa de manera diferente.

Supongamos que, en lugar de implementar un objeto cvar, SWIG simplemente usó PyInt , etc., como atributos de los módulos generados (que es lo que hacen las extensiones C “normales”). Luego, cuando, desde el código de Python, el usuario asigna un valor a la variable, se asigna un nuevo objeto PyInt a ese atributo, pero la variable original utilizada por la biblioteca no cambia , porque el objeto del módulo no sabe que tiene que modificar el C- Variable global al realizar una asignación.

Esto significa que, si bien desde el lado de python el usuario verá el cambio de valor, la biblioteca C no sería consciente del cambio porque la ubicación de la memoria representada por la variable global no cambió su valor.

Para permitir que el usuario establezca los valores de una manera que sea visible desde la biblioteca C / C +, SWIG tuvo que definir este objeto cvar , el cual, al realizar asignaciones, asigna el valor a la variable de la biblioteca debajo de la cubierta, es decir, cambia el contenido de la ubicación de la memoria que contiene el valor de la variable global.

Probablemente, esto se hace proporcionando una implementación de __setattr__ y __getattr__ o __getattribute__ , de modo que cvar pueda anular el comportamiento de asignación a un atributo.