简体   繁体   English

在导入的代码库之间传递对象的Pythonic方法是什么?

[英]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). 我有一个程序导入两个模块,一个我们将调用operations (这只是一系列功能),另一个我们称为tracking (这是一个类)。 The program tracking module monitors a series of messages, has some error state flags, and so forth. 程序tracking模块监视一系列消息,具有一些错误状态标志,等等。 The program sorts information in tracking by severity and relevant parties, then dumps this to different files at the end. 该节目种类信息tracking的严重程度和有关各方,然后在最后甩掉这个不同的文件。

I create a single instance of the tracking class with myTrack = tracking.Tracking() . 我使用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. 不幸的是,我想在operations模块中使用我的tracking对象,只是为了跟踪错误和警告。 It looks like I can pass myTrack to functions in the operations module as an argument, modifying each and every one of the functions. 看起来我可以将myTrack作为参数传递给operations模块中的函数,修改每个函数。

However, is there a "better" or "more Pythonic" way to do this? 但是,有没有“更好”或“更多Pythonic”的方式来做到这一点? 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. 有很多方法可以重构这个,但是你可以开始的一个地方是在你的operations模块中添加一个track()函数。 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. 在您的operations模块中,您可以在想要跟踪某些内容的任何地方调用track()函数。

Assuming your Tracking object has a method called track() that does the actual tracking, then in your main module, you can do this: 假设您的Tracking对象有一个名为track()的方法来执行实际跟踪,那么在主模块中,您可以执行以下操作:

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

This replaces the module's (do-nothing) track function with the method from your Tracking instance. 这将使用Tracking实例中的方法替换模块的(无操作) track功能。

Basically, you have provided a "hook" which anyone can use to add tracking to your operations module, and then used that hook yourself. 基本上,您提供了一个“钩子”,任何人都可以使用它来向您的operations模块添加跟踪,然后自己使用该钩子。

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 . 我认为更好的想法是定义一个Operations类,它包含您作为方法所需的所有函数以及持有Tracking实例。 You can just pass in your Tracking object and create an Operations instance, and use that to call whatever function that you need. 您只需传入Tracking对象并创建一个Operations实例,然后使用它来调用您需要的任何函数。

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. 您的tracking模块(记录有关一系列事件的详细信息以供以后分析或显示)听起来很像标准库的logging模块。 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). 如果您决定沿着那条路走,那么operations模块只会将事件记录到特定的记录器(例如“myapp.operations”),您的tracking模块将提供一个记录处理程序,它可以执行您想要的操作,并且您的主模块将挂钩两者一起(通过使用“myapp.operations”记录器注册跟踪处理程序)。

You can also set up something like that yourself, but really, if you want to track events in a Python program... just use logging . 您也可以自己设置类似的东西,但实际上,如果您想在Python程序中跟踪事件......只需使用logging

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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