Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么cProfile会导致函数返回不同的值?_Python_Python 3.x_Cprofile - Fatal编程技术网

Python 为什么cProfile会导致函数返回不同的值?

Python 为什么cProfile会导致函数返回不同的值?,python,python-3.x,cprofile,Python,Python 3.x,Cprofile,我正在用Python(3.3.1)构建一个模型,用于一个相当简单但却非常灵活的长期现金流合同。就时间消耗而言,完整的模型相当复杂,因此我决定尝试分析它。然而,我得到了不同的答案,有没有剖析 我已将代码简化为以下示例: def generate_cashflows( income ): contingent_expense = [1000.0] income_cf = [income] outgo_cf = [ -0.001 * contingent_expense[0]

我正在用Python(3.3.1)构建一个模型,用于一个相当简单但却非常灵活的长期现金流合同。就时间消耗而言,完整的模型相当复杂,因此我决定尝试分析它。然而,我得到了不同的答案,有没有剖析

我已将代码简化为以下示例:

def generate_cashflows( income ):
    contingent_expense = [1000.0]
    income_cf = [income]
    outgo_cf = [ -0.001 * contingent_expense[0] ]
    bank = [ income_cf[0] + outgo_cf[0] ]

    for t in range(1, 20):
        contingent_expense.append(1000.0)
        income_cf.append( income )
        outgo_cf.append( -contingent_expense[t] * 0.001 )
        bank.append(    bank[t-1] * (1+0.05)**(1/12)
                + income_cf[t]
                + outgo_cf[t]
                )
    return bank[-1]

print(str(generate_cashflows(0)))
输出:

calum@calum:~/pricing/model$ ./scratch.py 
-20.793337746348953
calum@calum:~/pricing/model$ python -m cProfile scratch.py
-20.0
     80 function calls in 0.000 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.000    0.000 scratch.py:5(<module>)
    1    0.000    0.000    0.000    0.000 scratch.py:5(generate_cashflows)
   76    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    1    0.000    0.000    0.000    0.000 {range}


calum@calum:~/pricing/model$ 
calum@calum:~/pricing/model$/scratch.py
-20.793337746348953
calum@calum:~/pricing/model$python-m cProfile scratch.py
-20.0
在0.000秒内调用80个函数
订购人:标准名称
ncalls tottime percall cumtime percall文件名:lineno(函数)
1 0.000 0.000 0.000 0.000划痕。py:5()
1 0.000 0.000 0.000 0.000划痕。py:5(生成现金流)
76 0.000 0.000 0.000 0.000{“列表”对象的“附加”方法}
1 0.000 0.000 0.000 0.000{方法'disable'的''lsprof.Profiler'对象}
1 0.000 0.000 0.000 0.000{范围}
calum@calum:~/定价/型号$

为什么每次都会输出不同的答案,有没有简单的解释?我已经看过手册了,但没有看到任何明显的东西

首先,我尝试使用python3进行复制,运行“python3 scratch.py”和“python3-m cProfile scratch.py”都打印-20.7933。。。在我的机器上

python2.x上返回-20.0的原因是因为除数运算符“/”在python2.x()中的工作方式不同

在python2中,1/12==0

在python3中,1/12==0.08333333

这意味着在python2中

 bank.append(    bank[t-1] * (1+0.05)**(1/12)
简化为

 bank.append(    bank[t-1] * (1+0.05)**(0)

这可能不是你想要的。python3的解释可能是正确的,python2的解释是相当无用的。作为补充说明,将(1/12)更改为(1.0/12)将在python2和python3上产生相同的输出,并将使代码返回相同的输出,无论是否进行分析,但这只是处理症状,而不是原因

关于为什么使用和不使用评测时会得到不同的输出,我的最佳猜测是,您使用的是不使用评测的python3和使用评测的python2。在运行代码时使用相同版本的python,无论是否使用评测,都是获得有意义结果的关键

您正在使用./scratch.py的事实表明您可能有一行

#!/usr/bin/python3
在scratch.py的顶部(尽管提供的代码中没有包含它)。 当你跑的时候

./scratch.py
python -m cProfile scratch.py
/usr/bin/python3用于执行该文件

当你跑的时候

./scratch.py
python -m cProfile scratch.py
默认的python解释器用于执行该文件(我猜是python2)

如果从命令行运行“python”(不带任何其他参数),您可能会看到默认的intepreter是2.X

因此,让您的代码返回相同的输出(有评测和没有评测)应该很简单,就像在评测时指定python3一样:

 python3 -m cProfile scratch.py

不是答案,但我在Windows中用Python2.7.3尝试了您的代码,无论是否使用profiling.Hmm,它都会给出相同的结果(-20.0)。神秘!好的,在这里用2.7运行,两方面都得到20.0。哦,天哪,我真不敢相信我没有看到。非常感谢你指出我的愚蠢。