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

2024-04-27 03:36:17 发布

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

我正在用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$ 

有没有一个简单的解释为什么每次都会输出不同的答案?我看了手册,但没看到明显的东西。你知道吗


Tags: py模型modelgeneratecfbankscratchappend
1条回答
网友
1楼 · 发布于 2024-04-27 03:36:17

首先,我尝试用python3复制,并运行“python3”刮痕.py“和”Python3-m cProfile刮痕.py“都印了-20.7933。。。在我的机器上。你知道吗

python2.x上返回-20.0的原因是除数运算符“/”在python2.x(http://legacy.python.org/dev/peps/pep-0238/)中的工作方式不同

在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)

或者

 bank.append(    bank[t-1] * 1

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

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

你正在使用的事实/刮痕.py表示您可能有一行

#!/usr/bin/python3

在顶部刮痕.py(尽管所提供的代码中没有包含它)。 当你跑的时候

./scratch.py

/usr/bin/python3用于执行文件

当你跑的时候

python -m cProfile scratch.py

默认的python解释器用于执行文件(我猜是python2)

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

因此,让您的代码返回相同的输出,无论是否进行分析,都应该像在分析时指定python3一样简单:

 python3 -m cProfile scratch.py

相关问题 更多 >