这个C/ c++代码在Python中的等效代码是什么?

void foo()
{
    static int counter = 0;
    counter++;
    printf("counter is %d\n", counter);
}

具体来说,如何在函数级别实现静态成员,而不是在类级别?将函数放入类中会改变什么吗?


当前回答

其他解决方案将计数器属性附加到函数,通常使用复杂的逻辑来处理初始化。这对于新代码是不合适的。

在Python 3中,正确的方法是使用非局部语句:

counter = 0
def foo():
    nonlocal counter
    counter += 1
    print(f'counter is {counter}')

有关非局部语句的规范,请参阅PEP 3104。

如果计数器是模块私有的,则应该将其命名为_counter。

其他回答

Python没有静态变量,但你可以通过定义一个可调用的类对象,然后将其用作函数来伪装它。也可以看看这个答案。

class Foo(object):
  # Class variable, shared by all instances of this class
  counter = 0

  def __call__(self):
    Foo.counter += 1
    print Foo.counter

# Create an object instance of class "Foo," called "foo"
foo = Foo()

# Make calls to the "__call__" method, via the object's name itself
foo() #prints 1
foo() #prints 2
foo() #prints 3

注意,__call__使类(对象)的实例可以通过自己的名称调用。这就是为什么上面调用foo()会调用类的__call__方法。从文档中可以看到:

任意类的实例都可以通过在类中定义__call__()方法来实现可调用。

当然,这是一个老问题,但我想我可以提供一些更新。

看来性能论点已经过时了。 对于siInt_try和isInt_re2,相同的测试套件似乎给出了类似的结果。 当然,结果会有所不同,但这是在我的计算机上使用python 3.4.4的一次会话,使用Xeon W3550的内核4.3.01。 我已经运行了几次,结果似乎相似。 我将全局正则表达式移动到函数静态,但性能差异可以忽略不计。

isInt_try: 0.3690
isInt_str: 0.3981
isInt_re: 0.5870
isInt_re2: 0.3632

考虑到性能问题,try/catch似乎可以生成最适合未来和墙角情况的代码,所以可能只是将其包装在函数中

在尝试了几种方法后,我最终使用了@warvariuc的答案的改进版本:

import types

def func(_static=types.SimpleNamespace(counter=0)):
    _static.counter += 1
    print(_static.counter)

根据丹尼尔的回答(补充):

class Foo(object): 
    counter = 0  

def __call__(self, inc_value=0):
    Foo.counter += inc_value
    return Foo.counter

foo = Foo()

def use_foo(x,y):
    if(x==5):
        foo(2)
    elif(y==7):
        foo(3)
    if(foo() == 10):
        print("yello")


use_foo(5,1)
use_foo(5,1)
use_foo(1,7)
use_foo(1,7)
use_foo(1,1)

我想添加这一部分的原因是,静态变量不仅用于增加某个值,而且还用于检查静态变量是否等于某个值,作为一个现实生活中的例子。

静态变量仍然受到保护,并且仅在函数use_foo()的作用域内使用。

在这个例子中,调用foo()函数完全是(相对于相应的c++等效函数):

stat_c +=9; // in c++
foo(9)  #python equiv

if(stat_c==10){ //do something}  // c++

if(foo() == 10):      # python equiv
  #add code here      # python equiv       

Output :
yello
yello

如果类Foo被严格定义为一个单例类,那将是理想的。这将使它更加python化。

Soulution n +=1

def foo():
  foo.__dict__.setdefault('count', 0)
  foo.count += 1
  return foo.count