Here's a slightly neater version that wraps up access to Tcl's global variables as a Python class:
import tkinter
class TclGlobalVariables(object):
def __init__(self, tclsh):
self.tclsh = tclsh
def __setattr__(self, name, value):
if name == "tclsh":
object.__setattr__(self, name, value)
else:
# The call method is perfect for this job!
self.tclsh.call("set", "::" + name, str(value))
def __getattr__(self, name):
if name == "tclsh":
return object.__getattr__(self, name)
else:
# Tcl's [set] with only one argument reads the variable
return self.tclsh.call("set", "::" + name)
Demonstrating it:
tcl = TclGlobalVariables(tkinter.Tcl())
# Write to a Tcl variable
tcl.x = 123
# Read from it
print("From Python: x =", tcl.x)
# Show that it is really there by sending commands to the underlying Tcl interpreter
tcl.tclsh.eval('puts "From Tcl: x = $x"')
# Show that manipulations on the Tcl side are carried through
tcl.tclsh.eval('incr x 2')
print("From Python again: x =", tcl.x)
# Show that manipulations on the Python side are carried through
tcl.x += 3
tcl.tclsh.eval('puts "From Tcl again: x = $x"')
Which produces this output:
From Python: x = 123
From Tcl: x = 123
From Python again: x = 125
From Tcl again: x = 128
Note that this assumes that you are only accessing simple global variables on the Tcl side (not namespaced variables and not arrays) and doesn't handle type mapping. Deeper levels of mapping are possible… but get really complicated.