替换全局变量

2024-04-29 15:07:53 发布

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

下面,我提出了人工地将引用变量n2f2()传递到g2(x),而不是f()中的全局变量n和嵌套的g()。在这种情况下,还有其他更好的方法来替换全局变量吗?你知道吗

from random import randint

# global value var
def f():
    global n
    n=0    
    def g(): 
        global n
        if randint(1,100)>50: n+=1    
    for _ in range(100): g()
    print(n)

# local reference var
def f2():
    n2=[0]
    for _ in range(100): g2(n2)
    print(n2[0])    
def g2(x):
    if randint(1,100)>50: x[0]+=1

Tags: inforifvardef情况rangeglobal
2条回答

从使用函数语言开始,从尝试编写可复制的测试开始,我通常尝试采用这样一个规则:函数应该将其所有输入声明为参数,并将其所有输出生成为返回值:在最大可能的范围内,函数不应该有副作用。使用global关键字可能表示您违反了此规则。你知道吗

例如,您的“g”函数接受当前状态变量,或者递增,或者不递增。您不需要全局变量(也不需要它是嵌套函数):

from random import randint
def g(n):
    """Returns either n or n+1, with 50% probability."""
    if randint(1,100)>50:
        return n+1
    else:
        return n

然后迭代函数可以多次调用:

def f():
    """Produces a number between 0 and 100 with $DISTRIBUTION."""
    n = 0
    for _ in range(100):
        n = g(n)
    return n

最后在高层:

if __name__ == '__main__':
    print(f())

因为我们从来都不能完全确定我们的代码,所以我们可以编写一些测试。你知道吗

def test_f():
    n = f()
    assert n >= 0 and n < 100

def test_g():
    n = g(0)
    assert n == 0 or n == 1

def test_g_dist():
    count = 100
    ns = [g(0) for _ in range(count)]
    assert(all(n == 0 or n == 1) for n in ns)
    zeros = len([n for n in ns if n == 0])
    ones = len([n for n in ns if n == 1])
    assert zeros + ones == count
    # won't always pass; probability of failure left as an exercise
    assert zeros > 0.45 * count and zeros < 0.55 * count

注意,我可以调用f()g(n)任意多次,它们不会干扰其他任何东西。在启动时运行我自己的单元测试会有点不寻常,但如果我想这样做的话,我可以自由选择。你知道吗

简短回答:您试图通过引用传递一个不可变的值(整数)并希望更新它。把它包装在一个很小的班级里,或者列表里,或者像你现在做的那样口述。但是,如果您能够稍微修改代码,还有其他方法。你知道吗

较长的答案:(注意:这可能不是您问题的直接答案。)

我知道这是一个人为的例子。但是想想你真正的问题g2()是否需要知道有一个变量应该作为其调用的一部分进行更新?有没有一种方法可以让更新变量的责任属于定义变量的责任?f2()是定义变量并更新它的那个吗?这样就可以将对该变量的所有更改限制在一个非常小的周长(f2())。你知道吗

在这种情况下,我的方法是:

def f2():
    n2 = 0
    for _ in range(100):
        n2 += g2()
    print(n2)

def g2():
    return 1 if randint(1,100)>50 else 0

相关问题 更多 >