从子modu调用时对象工作不正常

2024-10-04 03:18:53 发布

您现在位置:Python中文网/ 问答频道 /正文

你好,慷慨的朋友们

这是一个有点复杂的问题,但希望与子模块中全局对象的更一般用法有关。你知道吗

我正在使用一些商业软件,这些软件提供了一个python库,用于通过TCP与它们的应用程序接口。(我想我不能发布他们库的代码。)

我在从子模块调用对象时遇到了一个问题,我认为它通常与全局变量或类似的一些变量有关。基本上,当子模块与所有其他模块(包括创建对象的模块)位于同一目录中时,对象的状态与预期相同。
但是当我将有问题的子模块移动到子文件夹中时,它仍然可以访问该对象,但状态似乎已被更改,并且该对象与商业应用程序的连接不再工作。你知道吗

根据this question关于全局变量的一些建议,我将模块的文件组织如下:

scriptfile.py
pyFIMM/
    __init__.py            # imports all the other files
    __globals.py           # creates the connection object used in most other modules
    __pyfimm.py            # main module functions, such as pyFIMM.connect()
    __Waveguide.py         # there are many of these files with various classes and functions
    (...other files...)
    PhotonDesignLib/
        __init__.py        # imports all files in this folder
        pdPythonLib.py     # the commercial library
    proprietary/
        __init__.py        # imports all files in this folder
        University.py      # <-- The offending child-module with issues

pyFIMM/__init__.py像这样导入子文件:

from __globals import *         # import global vars & create FimmWave connection object `fimm`
from __pyfimm import *          # import the main module
from __Waveguide import *.
(...import the other files...)
from proprietary import *      # imports the subfolder containing `University.py`

子文件夹“PhotonDesignLib”&;“privative”中的__init__.py都会导致导入子文件夹中的所有文件,因此,例如,scriptfile.py将访问我的专有文件,如下:import pyFIMM.proprietary.University。这是通过this hint实现的,在proprietary/__init__.py中编码如下:

import os, glob
__all__ = [ os.path.basename(f)[:-3] for f in glob.glob(os.path.dirname(__file__)+"/*.py")]

(来自几个不同机构的众多编码人员将拥有自己的专有代码,因此我们可以共享基本代码,但这样我们就可以保留自己的专有文件/函数,而不必更改任何基本代码/导入语句。我现在意识到,对于更静态的PhotonDesignLib文件夹,这是一种过度杀戮。)

文件__globals.py创建了我需要用来与他们的商业应用程序通信的对象,代码如下(这是该文件中的所有代码):

import PhotonDesignLib.pdPythonLib as pd    # the commercial lib/object
global fimm
fimm = pd.pdApp()      # <- - this is the offending global object

我的所有子模块都包含一个from __global import *语句,并且能够访问对象fimm,而无需特别声明它为global变量,没有任何问题。你知道吗

所以我运行scriptfile.py,它有一个类似于from pyFIMM import *的import语句。 最重要的是,scriptfile.py在发出任何需要通信的命令之前,通过顶部的fimm.connect()启动与应用程序的TCP连接,所有其他模块在各种例程中调用fimm.Exec(<commands for app>),这些例程一直运行得很好fimm对象到目前为止,所有模块都可以访问,并保持连接状态。你知道吗

我遇到的问题是,文件proprietary/University.py只能成功地使用fimm对象,当它放在pyFIMM根目录(即与__globals.py等相同的文件夹)中时。但是当University.pyproprietary子文件夹中导入时,它会给我一个“应用程序未初始化”错误我使用fimm对象,就好像对象被覆盖或重新初始化了一样。对象仍然存在,只是在被这个子模块调用时没有保持它的连接状态。(我已经检查过它没有在另一个模块中重新初始化。)

如果脚本在proprietary/University.py中失败后,我使用控制台发送一个命令,例如pyFimm.fimm.Exec(<command to app>)它可以正常通信
我在一开始就将proprietary/University.py设置为将dir(fimm)打印为测试,这样做很好,看起来fimm对象如预期的那样存在,但是在同一个文件中对fimm.Exec()的后续调用表明对象的状态不正确,返回“application not initialized”错误。
这看起来几乎有两个fimm对象—一个是主python控制台(和pyFIMM模块)看到的,它工作得很好;另一个是proprietary/University.py看到的,它不知道我们已经调用了fimm.connect()。同样,如果我将University.py放在主模块文件夹“pyFIMM”中,它工作正常fimm.Exec()调用按预期运行!你知道吗

仅供参考proprietary/University.py按如下方式导入__globals.py文件:

import sys, os, inspect
ScriptDir = inspect.currentframe().f_code.co_filename   # get path to this module file
(ParentDir , tail) = os.path.split(ScriptDir)       # split off top-level directory from path
(ParentDir , tail) = os.path.split(ParentDir)       # split off top-level directory from path
sys.path.append(ParentDir)        # add ParentDir to the python search path

from __globals import *         # import global vars & FimmWave connection object

global fimm         # This line makes no difference, was just trying it.

(仅供参考,Som)因此有人说inspect__file__好,因此上面的代码是这样的。)

为什么您认为子模块位于子文件夹中会导致对象失去其状态?

我怀疑问题要么是我指示University.py导入__globals.py的方式,要么是我在proprietary/__init__.py中使用的“导入此文件夹中的所有文件”方法。但我不知道怎么修!你知道吗

感谢您关注这个问题,并提前感谢您的见解。你知道吗


Tags: 模块文件thepath对象代码frompy