简体   繁体   中英

What is the most Pythonic way to pass objects between imported libraries of code?

I have a program which imports two modules, one we will call operations (which is just a series of functions) and the other we call tracking (which is a class). The program tracking module monitors a series of messages, has some error state flags, and so forth. The program sorts information in tracking by severity and relevant parties, then dumps this to different files at the end.

I create a single instance of the tracking class with myTrack = tracking.Tracking() . (Yes, this is global state and therefore bad , but it is pretty handy)

Unforunately, I would like to use my tracking object within the operations module, just to track errors and warnings. It looks like I can pass myTrack to functions in the operations module as an argument, modifying each and every one of the functions.

However, is there a "better" or "more Pythonic" way to do this? I suspect there is something with namespaces which I have failed to grasp.

There are a lot of ways you could refactor this, but one place you might start is to add a track() function to your operations module. Have it do nothing by default.

 def track(message):  # use the right signature though!
     pass

In your operations module you would then call your track() function anywhere you might want to track something.

Assuming your Tracking object has a method called track() that does the actual tracking, then in your main module, you can do this:

myTrack = tracking.Tracking()
operations.track = myTrack.track

This replaces the module's (do-nothing) track function with the method from your Tracking instance.

Basically, you have provided a "hook" which anyone can use to add tracking to your operations module, and then used that hook yourself.

Yes, this is more "global state," but it's module-global, which is not really global.

I am not sure I understand your problem correctly, but I think you are looking for a way to make the functions in one module automatically aware of the state an object in another module without explicitly passing that object every time you call a function.

The basic problem is that at some level you have to pass the object and have it available to all the functions you need. Modules are simply not meant to work like that.

I think a better idea will be to define an Operations class that contains all the functions you need as methods as well as holding an instance of Tracking . You can just pass in your Tracking object and create an Operations instance, and use that to call whatever function that you need.

myTrack = tracking.Tracking()
myOperation=operations.Operations(myTrack)
myOperation.doSomething()

Your tracking module (recording details about a series of events for later analysis or display) sounds suspiciously like the standard library's logging module. So you may want to investigate that a little more closely.

If you decide to head down that path, then the operations module would just log events to a specific logger (eg "myapp.operations"), your tracking module would provide a logging handler that did what you wanted, and your main module would hook the two together (by registering the tracking handler with the "myapp.operations" logger).

You can also set up something like that yourself, but really, if you want to track events in a Python program... just use logging .

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