简体   繁体   中英

What is the most pythonic way to structure a multi-module python program?

I've built a fairly sizeable program in a single file. The size of the file was making it unworkable, so I decided to split into multiple modules, but have since had a major headache of variable scope. I've largely fixed it (with a fair bit of learning along the way), but I'm keen to understand good structuring to avoid future lessons learnt the hard way. There are a couple of specific points, but general advice is also welcome.

Modules that need to share the same namespace

I have two modules that seem to need to share the same namespace. One is the main flow of the program (which transfers data to and from objects, and calls the UI), the other is the UI (which responds to user input, calling the main flow).

Should each of these modules import the other, and then the main file import both? That doesn't seem particularly elegant to me.

from [modulename] import *

In the answers to this question:

Python: Sharing global variables between modules and classes therein

There is a suggestion that from [modulename] import * should be avoided.

Is it OK to use from [modulename] import * to build together a load of modules that just have class definitions? What are "safe" use cases?

Modules that need to access each other's namespace is not the same as modules that need to share the same namespace. I can't think of anything you can do with from modulename import * that you can't do with import modulename . You just have to preface a lot of your names with modulename. That's a good thing, not a bad thing. It makes your code self-documenting, which is why from modulename import * is to be avoided.

You can have the UI and main flow modules import each other. The only way you'll run into problems is if you reference names between them outside of the scope of functions. For example

# mainflow.py
import ui # interpreter stops reading mainflow and starts reading ui

class Foo:
    ...

theUI = ui.UI()

# ui.py
import mainflow # mainflow already being loaded; interpretation of ui continues uninterrupted

def dosomething():
    myfoo = mainflow.Foo() # so far so good, not interpreted until the function is called

class Bar(mainflow.Foo): # mainflow.Foo not reached yet, error here
    ...

class UI:
    ...

On the other hand if ui happens to get imported first, then you get the error at theUI = ui.UI() , when all of mainflow has been interpreted but ui has only been interpreted as far as import mainflow . As long as you put all the references to each other inside functions, though, you can get along fine. Eg

# mainflow.py
import ui
...

theUI = None

def initialize():
    global theUI
    theUI = ui.UI()

There's still a problem with the dependency between the classes; I recommend you don't do anything like that. But if you did, you could make the whole thing work with this strange approach:

# mainflow.py
...

theUI = None

def initialize():
    global theUI
    theUI = ui.UI()

import ui # Waht!? Crazy! Import at the bottom of a file. Now all of mainflow's names are guaranteed to exist and ui can access them.

Now with the first version of ui.py and the last version of mainflow.py, the program would compile and run. I don't really recommend the above; better organize your code so you don't have such dependencies. But if all you have is calls back and forth between functions in modules, you don't have to resort to such tricks.

There are more object-oriented designy ways to make your UI and your program flow not directly depend on each other, but such a redesign would be more involved than just copy and paste to files and prefacing names with module. I don't think you want to go overboard with your redesign unless you have a specific reason.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM