为什么代码中的“失落的天堂”在py2.7中运行了很多个月,现在在名称空间中找不到np.ndarray(),而[import numpy as np]被执行了?

hzbexzde  于 2023-03-08  发布在  其他
关注(0)|答案(2)|浏览(132)

我的问题是:在2.7.9和2.7.11之间是否有任何名称空间处理更改?
(我努力缩小/隔离的问题,但由于下述原因,它实际上是不可能的后MCVE).
下面发布的体内诊断已经证明,在尝试访问/使用numpy(np)符号的第一行(第14644行,原始编号为14630)之前,np.ndarray调用不存在命名空间问题

aDSegFLOAT = np.ndarray( ( 80, 7 ), ...

其中正在工作的numpy调用突然引发异常:
未绑定本地错误:赋值前引用了局部变量"np"

    • 简介:**

为了进行定量建模,在用于技术分析和预测的分布式处理框架中重新使用了相当广泛的python模块代码。(用于预测)是以小的CPU核小时的显著成本生成的,部署了一些附加措施以允许有状态模块reload( QuantFX )-s,从而这些保护了量化模型的已经详细阐述的示例,但是允许模块功能被更新、调整和在运行中重新测试。

    • 事实:**

import QuantFX停止工作,并在未修改的numpy调用上引发异常:

  • 大约在过去12个月内使用了模块代码,仅更新了[QUANT-TOOLS]、[MODEL]部分
  • 代码是多方分布式处理的Python 2.7部分,因此MCVE的尝试将永远不会反映/复制生态系统行为
    • 问题出现的时间:**

在加载了最近的水蟒之后(miniconda 4.0.0/4.0.5)用于VM02/wXP主机的软件包管理器,此外,python已被重新修改为2.7.11和名为QuantFX.py的模块,在此更新之前,在其他Anaconda 2.2.0中运行没有任何问题python 2.7.9中的(32位)安装停止工作,出现一个外观奇怪的异常

    • 哪些情况表明运行状态不佳:**

import QuantFX运行良好,就像它在过去的十几个月里一样,一周一周地运行,现在调用QuantFX.aMiniRESPONDER()会导致一个异常/产生一个Traceback,就好像numpy根本不是import-ed(参见第221行)而是某个局部变量一样。

... 
    [aMiniRESPONDER]: messaging & signalling sockets RTO:<infrastructure-setup>
    START:
           Sun Apr 17 20:19:33 2016 ...
    [aMiniRESPONDER]: final attempt to de-block a remote-processing failed at aXmitSOCKET.send()
    
    SIG->: Sun Apr 17 20:19:33 2016 PUB-lished a <_|SIG_EXIT|_> signal to peers, will sleep( 3 ) to allow for reception
    ZMQ:
           Sun Apr 17 20:19:36 2016 Graceful Exit Done. RET(0)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "QuantFX.py", line 14630, in aMiniRESPONDER
        aDSegFLOAT= np.ndarray( ( 80, 7 ),
    UnboundLocalError: local variable 'np' referenced before assignment

(虽然在解释器命令行提示符上手动调用非常相同的numpy函数,
关于模块将numpy转换为importnamespace(下面的第221行)
进展顺利

|>>> QuantFX.np.ndarray( ( 2, 3 ), dtype = QuantFX.np.float32, order = 'F' )
array([[  1.22325565e+10,  -2.81789980e-05,   1.22325565e+10],
       [  1.91215026e+00,  -1.81719875e+00,   1.91215026e+00]], dtype=float32)
+0:00:13.282000
22:20:54
|
|>>> QuantFX.np.__version__
'1.10.4'
+0:00:24.438000
22:21:18
|

).

第14630行Traceback的上下文和详细信息:

第221行import numpy as np+状态-满载钉仓的概念:

尽管QuantFX模块编码可能引起关于PEP * 等人的异议,语法构造器被确定为允许通过import/reload()的全上下文操作方式,以及通过选择/复制/粘贴用于诊断或控制CLI目的的单个组件代码,在消耗最小RAM/CPU的远程终端中的快速和安全的无上下文轻量操作(如aRemoteKEYBOARD()aMiniRESPONDER()),但不需要import整个QuantFX模块(提供后期导入,包括用于这种QuantFX的所述numpy(行14426)-无上下文操作方式)。

所需内容:

关于2.7.9和2.7.11之间的变化的任何解释,可能与上周五刚刚介绍的观察到的np.ndarray()碰撞有关。
任何关于替代模块语法构造器布局的建议也是很有价值的,如果这样的建议既保留了reload( QuantFX )期间的状态性,又允许上下文完整和上下文无关的代码库组件使用的话。

更新:

与其可能出现的情况相反,在发布之前进行了适当的审查和调试工作,以添加体内自我诊断,从而允许隔离问题

""" DEBUG: VM02, after about-a-year working here stable... THROWS EXC. HERE: "UnboundLocalError: local variable 'np' referenced before assignment"                                 ????? .EXC on np.ndarray()
            >>> import QuantFX
            Is QuantFX_FLAG seen in dir() during <module> import:  True
            SECTION: ____IDENTIFY____ [TRY].OK
            SECTION: ____IDENTIFY____ [FIN]
            SECTION: import           [TRY].OK
            SECTION: import           [FIN]
            SECTION: FX-MARKET CONTEXTs [TRY].OK
            SECTION: FX-MARKET CONTEXTs [FIN]
            SECTION:    GENERAL TOOLS [TRY].OK
            SECTION:    GENERAL TOOLS [FIN]
            SECTION:     DATA INPUTs [TRY].OK
            SECTION:     DATA INPUTs [FIN]
            SECTION: v41 PROCESS [TRY].OK
            SECTION: v41 PROCESS [FIN]
            SECTION: v41 QUANT TOOLS [TRY].OK
            SECTION: v41 QUANT TOOLS [FIN]
            QuantFX.py:10966: RuntimeWarning: invalid value encountered in divide
            ST2  = np.where( ST2 != 0, ( ST[-LLV.shape[0]:] - LLV ) /  ST2, ST2 ) # / ST2 ( == HHV - LLV )          #        __main__:4162: RuntimeWarning: invalid value encountered in divide
            SECTION: v41 MODEL [TRY].OK
            SECTION: v41 MODEL [FIN]
            SECTION: v41 PREDICTOR [TRY].OK
            SECTION: v41 PREDICTOR [FIN]
            SECTION: MetaTrader RESPONDER [TRY].OK
            SECTION: MetaTrader RESPONDER [FIN]
            SECTION: ____TEMPLATE____ [TRY].OK
            SECTION: ____TEMPLATE____ [FIN]
            SECTION: ____TEMPLATE____ [TRY].OK
            SECTION: ____TEMPLATE____ [FIN]
            SECTION: ____TEMPLATE____ [TRY].OK
            SECTION: ____TEMPLATE____ [FIN]
            +0:00:01.219000
            18:20:14
            |
            |>>> QuantFX.aMiniRESPONDER( aTarget2Bind2_URL = "tcp://10.0.0.62:9999", anInstrumentDictOfPARAMs = QuantFX.anFxCTX[ QuantFX.aCtxID ] )
            [aMiniRESPONDER]: runs in it's own full QuantFX context
            [aMiniRESPONDER]: imports DONE
            [aMiniRESPONDER]: variables DONE
            [aMiniRESPONDER]: messaging & signalling sockets RTO:[aZmqCONTEXT] <class 'zmq.sugar.context.Context'> setup with 15.2.0 version
            [aMiniRESPONDER]: messaging & signalling sockets     [aXmitSOCKET]-pre
            [aMiniRESPONDER]: messaging & signalling sockets     (aXmitSOCKET)-to be instantiated-via a call to aZmqCONTEXT.socket( zmq.PAIR )
            [aMiniRESPONDER]: messaging & signalling sockets     [aXmitSOCKET]-post
            [aMiniRESPONDER]: messaging & signalling sockets     [aXmitSOCKET]-bind()
            [aMiniRESPONDER]: messaging & signalling sockets RTO:[aXmitSOCKET]
            [aMiniRESPONDER]: messaging & signalling sockets RTO:[aCtrlSOCKET]
            [aMiniRESPONDER]: messaging & signalling sockets RTO:[aSIGsSOCKET]
            [aMiniRESPONDER]: messaging & signalling sockets RTO:<infrastructure-setup>
            START:
                Sun Apr 17 20:19:33 2016 ...
            [aMiniRESPONDER]: final attempt to de-block a remote-processing failed at aXmitSOCKET.send()
            
            SIG->: Sun Apr 17 20:19:33 2016 PUB-lished a <_|SIG_EXIT|_> signal to peers, will sleep( 3 ) to allow for reception
            ZMQ:
                Sun Apr 17 20:19:36 2016 Graceful Exit Done. RET(0)
            Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
            File "QuantFX.py", line 14630, in aMiniRESPONDER
                aDSegFLOAT= np.ndarray( ( 80, 7 ),                    
            UnboundLocalError: local variable 'np' referenced before assignment

体内数字编号数组符号检查器

@viraptor的体内检查器创意提案

def debug_check_np_ndarray( aCallerSideInspectFrameINFO ):      # DEBUG-CHECK
        #ebug_check_np_ndarray( aCallerSideInspectFrameINFO = getframeinfo( currentframe() ) )
        #rom inspect import currentframe, getframeinfo              # EXTERNAL RESPONSIBILITY TO import + setup aCallerSideInspectFrameINFO .OnCall
        
        #ef         np_check():                                     # DEF:

        try:                                                        # TRY: np.*
            np.ndarray
            print 70*" ", "* NP: np.ndarray call [OK], FILE: ", aCallerSideInspectFrameINFO.filename, " LINE: ", aCallerSideInspectFrameINFO.lineno
            
        except:                                                     # EXC: found the issue
            print 70*" ", "* NP: np.ndarray call [**], FILE: ", aCallerSideInspectFrameINFO.filename, " LINE: ", aCallerSideInspectFrameINFO.lineno
            exc_type, exc_value, exc_traceback = sys.exc_info()             # prepare a traceback detail
            traceback.print_tb(  exc_traceback, limit = 5, file = sys.stdout )
            raise
            
        else:                                                       # ELSE: ok, passed
            #rint("* NP check ok")  # optionally add current function name via a traceback module
            return

启动时提供详细的逐行确认,在Line 14644aDSegFLOAT = np.ndarray( ... )崩溃之前,没有np. ndarray符号屏蔽

|>>> QuantFX.aMiniRESPONDER()
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14387
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14391
[aMiniRESPONDER]: runs in it's own full QuantFX context
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14395
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14404
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14410
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14412
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14419
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14423
[aMiniRESPONDER]: runs in a full QuantFX mode, few imports DONE
[aMiniRESPONDER]: imports DONE
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14441
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14443
[aMiniRESPONDER]: variables DONE
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14454
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14527
[aMiniRESPONDER]: messaging & signalling sockets RTO:[aZmqCONTEXT] <class 'zmq.sugar.context.Context'> setup with 15.2.0 version
[aMiniRESPONDER]: messaging & signalling sockets RTO:<infrastructure-setup>
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14626
START:
    Tue Apr 19 16:02:12 2016 ...
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14632
                                                                    * NP: np.ndarray call [OK], FILE:  QuantFX.py  LINE:  14643

[aMiniRESPONDER].FINALLY: will start attempts to de-block a remote-processing ( after a prior intentional SIG_EXIT or an unhandled EXC )
[aMiniRESPONDER]: final attempt to de-block a remote-processing failed at aXmitSOCKET.send()
[aMiniRESPONDER]: final attempt to propagate a signal to peers failed at aSIGsSOCKET.send()

EXC. ZmqError(ZMQError('No such file or directory')) on aSIGsSOCKET .setsockopt( zmq.LINGER, 0 ) / .close( aSIGsSOCKET )
EXC. ZmqError(ZMQError('No such file or directory')) on aCtrlSOCKET .setsockopt( zmq.LINGER, 0 ) / .close( aCtrlSOCKET )
EXC. ZmqError(ZMQError('No such file or directory')) on aXmitSOCKET .setsockopt( zmq.LINGER, 0 ) / .close( aXmitSOCKET )

ZMQ:
    Tue Apr 19 16:02:15 2016 Graceful Exit Done. RET(0)

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "QuantFX.py", line 14644, in aMiniRESPONDER
    aDSegFLOAT          = np.ndarray( ( 80, 7 ),                    #           #  DSegFLOAT[][]                                  ### ToDo.MS: size-independent ( 80+ )                   np.*()  :::::::::::::::
UnboundLocalError: local variable 'np' referenced before assignment
+0:00:10.734000
16:02:15
|
kupeojn6

kupeojn61#

从你所展示的代码来看,python更新不太可能改变截图中的任何内容。
可能改变的是环境,或者其他地方的代码,这些地方不应该设置aMiniRESPONDER_in_full_QuantFX_CONTEXT。如果设置了这个变量,import numpy as np会被注解,你会得到这里显示的异常。
一些调试思路:要么在调试器中运行,要么在您认为应该导入numpy的地方使用print-debug和break/print-很可能您会发现您只是没有进入这些分支。
另一个:一次改变一件事。如果我理解正确的话,你改变了:python,包管理器和部署环境一起运行,发现这些东西在你不理解的情况下不再工作了。回到原来的环境重新测试。然后升级python,什么都不做。重新测试。然后升级包管理器(但不是包!)。重新测试......直到你找到到底是什么改变破坏了你的应用程序。
另一个:当某件事失败而你无法恢复时(例如导入失败),不要继续。在第二张截图中,您在try块中看到了很多import语句,这些语句将忽略错误并继续执行。(L 328 - 332).如果你继续,有些东西会在后面爆炸.如果剩下的代码看起来像那样--是的,你会以无声的失败结束,并且不知道它们从哪里来。
另一个验证@hpaulj建议的例子。非常粗糙的方法:创建如下函数:

def np_check():
    try:
        np.ndarray
    except:
        # found the issue
        raise
    else:
        print("* NP check ok")  # optionally add current function name via traceback module

在代码中添加这些内容,找出np名称"消失"时的第一个位置。将第一个调用放在您希望工作的import之后,以便在错误之前至少看到一个"* NP check ok"。然后,您只需要在最后一次成功和第一次失败的位置之间添加更多检查,直到您隔离出导致问题的行。

im9ewurl

im9ewurl2#

我可以用一个简单的脚本重现你的错误--我导入一个模块并使用它一次,但是第二次使用它时,全局赋值被本地赋值屏蔽了。即使本地赋值发生在尝试使用之后,这种屏蔽也会发生。

import collections    
def foo1():
   dd=collections.defaultdict(list)
   return dd

def foo2():
   dd=collections.defaultdict(int)
   collections = []
   return dd

print foo1()
print foo2()

生产

2112:~/mypy$ python stack1.py
defaultdict(<type 'list'>, {})
Traceback (most recent call last):
  File "stack1.py", line 13, in <module>
    print foo2()
  File "stack1.py", line 8, in foo2
    dd=collections.defaultdict(int)
UnboundLocalError: local variable 'collections' referenced before assignment

搜索代码,或者可能是你调用的东西,寻找类似np=...的语句,首先看看QuantFX.aMiniRESPONDER,因为它是错误的直接上下文。
将测试函数更改为

def foo2():
   dd = foo1()
   collections = []
   return dd

不会产生错误。因此屏蔽的范围相当有限。

相关问题