Python namespaces: how to make unique objects available in other modules?

I am writing a small application (several KLOCs) of PyQt. I started writing it in nice modules for ease of understanding, but I rely on Python's namespace rules. At several points, it is important to create an instance of only one class object as a resource for other code.

For example: an object that represents Aspell, attached as a subprocess, offering a verification method (words). Another example: an application has one QTextEdit and another code that should call the methods of this singular object, for example. "ifEditWidget.document (). isEmpty () ..."

No matter where I create an instance of such an object, it can only be referenced in the code in this module, and the other is not. So, for example, the code of the editing widget cannot call the Aspell gateway object if the Aspell object is not created in the same module. Good, except that it is necessary for other modules.

The bunch class is proposed for this question , but it seems that I have the same problem: it is a unique object that can only be used in the module where it was created. Or am I generally missing a boat here?

OK suggested elsewhere, this seems like a simple answer to my problem. I just tested the following:

junk_main.py:

import junk_A singularResource = junk_A.thing() import junk_B junk_B.handle = singularResource print junk_B.look() 

junk_A.py:

 class thing(): def __init__(self): self.member = 99 

junk_B.py:

 def look(): return handle.member 

When I run junk_main, it prints 99. Thus, the main code can enter names into modules only for their intended purpose. I'm trying to come up with reasons, this is a bad idea.

+4
source share
3 answers

It turns out that the answer is simpler than I thought. As I already noted in this question, the main module can add names to the imported module. And any code can add elements to the object. Thus, a simple way to create an intermodular communication area is to create the main object, for example, say, IMC (for an intermodular communicator) and assign it as members, all that should be available for other modules:

 IMC.special = A.thingy() IMC.important_global_constant = 0x0001 

etc .. After importing any module, just assign IMC to it:

 import B B.IMC = IMC 

Now this is probably not the biggest idea in terms of software development. If you just restrict the IMC to store named constants, it acts like a C header file. If it's just to access singular resources, it looks like an extern link. But due to liberal Python rules, code in any module can modify or add members to IMC. Used in an undisciplined manner, โ€œwho changed itโ€ can be a debugging problem. If there are several processes, race conditions are a danger.

+2
source

You can access the objects in the module with an operator . as with function. So for example:

 # Module a.py a = 3 >>> import a >>> print aa 3 

This is a trivial example, but you can do something like:

 # Module EditWidget.py theEditWidget = EditWidget() ... # Another module import EditWidget if EditWidget.theEditWidget.document().isEmpty(): 

Or...

 import * from EditWidget if theEditWidget.document().isEmpty(): 

If you go along the import * from route, you can define a list with the name __all__ in your modules with a list of names (as strings) of all objects that you want your module to export to *. Therefore, if you want to export only the EditWidget file, you can do the following:

 # Module EditWidget.py __all__ = ["theEditWidget"] theEditWidget = EditWidget() ... 
+1
source

At several points, it is important to create an instance of only one class object as a resource for other code.

Instead of trying to create some kind of singleton factory, can you create a one-time object somewhere between the main entry point for the program and create an instance of the object that needs it? A one-time object can only be passed as a parameter to another object. Logically, then you will not create a one-time object more than once.

For instance:

 def main(...): aspell_instance = ... myapp = MyAppClass(aspell_instance) 

or...

 class SomeWidget(...): def __init__(self, edit_widget): self.edit_widget = edit_widget def onSomeEvent(self, ...): if self.edit_widget.document().isEmpty(): .... 

I do not know if it is enough enough, or if it is applicable to your situation. But honestly, the only time I found that I canโ€™t do this is on a CherryPy-based web server, where entry points were almost everywhere.

+1
source

All Articles