Hi @indexofrefraction, I think @zipit already almost everything but just to clarify.
Each Python element (aka a Python Script Tag, a Python Generator) have Python Scope not bound to another this will be way too risky and with some challenges regarding synchronization internally, so they are completely split and each scope is independent without the luck to communicate from one to another.
Message is a good way to go if you just want to communicate from one entity to another. As @zipit a message is just an integer register in our Maxon "Namespace" so we reserve this ID so we are sure that this ID is only about this particular Message and this integer value is not used to represent anything else than this Message. This way when an object received this particular integer value, we can ensure this is about this particular Message and can assume the data structure passed.
So if you want to use your own Message it's advertised to register this ID as you register a plugin ID this way you ensure that nobody will use this ID in their plugins for something else.
Finally, note there is the MSG_BASECONTAINER which allows sending a basecontainer directly, this can be quiet useful because a BaseContainer can have an ID (So you have a kind of sub-message ID, this can be useful within communication to know the current status of the communication). And in this BaseContainer you can also store the original sender and multiple values.
Find in the attached scene, 2 Python Generator that asks a Python Tag to do a different math operation, and set their respective name according to the result received from the Python Tag. (Just enable them, the main function will be triggered and then message functions)