-1

2.7.9 和 2.7.11 之间是否有任何命名空间处理更改?

TL;DR:在 Stack Overflow 上提供 450 多个答案后。我确实知道堆栈溢出规则并努力缩小/隔离问题,但由于以下所有原因,实际上不可能发布一个公平的 MCVE。

下面发布的体内诊断证明,np.ndarray 调用没有命名空间问题,直到第一行尝试访问/使用 numpy ( np )符号第 14644 行(原始编号为 14630)

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

在哪里工作的 numpy 调用突然引发异常:

UnboundLocalError:分配前引用的局部变量“np”


简介:
出于定量建模的目的,相当广泛的python模块代码正在用于技术分析和预测的分布式处理框架中重新使用。由于一个事实,即量化模型(用于预测)是以数十个 CPU 核心小时的显着成本生成的,因此部署了一些允许有状态模块reload( QuantFX )-s 的额外措施,以便这些保护已经详细说明的量化模型实例,但允许即时更新、调整和重新测试模块功能。

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

  • 模块代码使用了大约 12 个月,仅更新 [QUANT-TOOLS],[MODEL] 部分
  • 该代码是多方分布式处理的 Python 2.7 部分,因此尝试 MCVE 永远不会反映/复制生态系统行为

问题开始时:
在为主机加载最近的 Anaconda ( miniconda4.0.0 / 4.0.5 ) 包管理器VM02/wXP后,也python被重新装扮成 2.7.11 和一个名为 的模块QuantFX.py,直到此更新在其他 Anaconda 中运行没有任何问题python 中的 2.2.0(32 位)安装2.7.9停止工作,出现一个奇怪的异常

什么表明运行状态不佳:
十来个月,一周一周,一切 都很import QuantFX顺利。对 now 的调用会QuantFX.aMiniRESPONDER()导致异常/产生 a 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(虽然在解释器命令行提示符下手动调用相同的函数,
但考虑namespace到模块(下面的第 221 行)所进入的numpy位置很顺利import

|>>> 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和详细信息:

local-view-on-Traceback + 无上下文操作方式后期导入,包括。 numpy 线 14426

第 221 行import numpy as np+ State-Full 重载的概念:

![global-view-on-module + import numpy as np # Line 221

虽然模块编码可能会引起 PEP* 等人的反对意见,但语法构造函数的决定是为了允许通过/QuantFX实现上下文完整的操作方式,以及在极简 RAM/CPU 中快速安全的无上下文轻量级操作通过选择/复制/粘贴仅用于诊断或控制 CLI 目的(如or )的单个组件代码来使用远程终端,但不需要整个模块(提供后期导入,包括上述(第 14426 行)对于这种无上下文的作案手法)。importreload()aRemoteKEYBOARD()aMiniRESPONDER()importQuantFXnumpyQuantFX


寻求什么:

上周五刚刚介绍的关于 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

体内 numpy-nd.array-symbol-checker

来自@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 14644崩溃之前没有 np.ndarray 符号屏蔽aDSegFLOAT = 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
|            
4

2 回答 2

6

从您显示的代码来看,python 更新不太可能/不可能更改截屏代码中的任何内容。

可能会改变的是环境,或者其他地方的代码应该不设置aMiniRESPONDER_in_full_QuantFX_CONTEXT。如果设置了该变量,import numpy as np则会对其进行注释,并且您会看到此处显示的异常。

一些调试想法:要么在调试器中运行,要么print在你认为应该导入 numpy 的地方使用 -debug 和 break/print - 可能你会发现你只是没有进入那些分支。

另一种:一次改变一件事。如果我正确理解了这个问题,你就改变了:python、包管理器和部署环境,并发现这些东西不再以你不理解的方式工作。回到原来的环境,重新测试。然后升级python,仅此而已。重新测试。然后升级包管理器(但不是包!)。重新测试。...直到您确切地找到哪个更改破坏了您的应用程序。

另一个:当某些事情失败并且您无法从中恢复时(例如导入失败),不要继续。在第二个屏幕截图中,您import在一个块中有很多语句try,它们将简单地忽略错误并继续执行。(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”。然后你只需要在最后一次成功和第一次失败之间添加更多检查,直到你隔离导致问题的行。

于 2016-04-19T03:51:04.227 回答
4

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

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

不会产生错误。所以掩蔽的范围相当有限。

于 2016-04-19T04:15:33.460 回答