这个C/ c++代码在Python中的等效代码是什么?
void foo()
{
static int counter = 0;
counter++;
printf("counter is %d\n", counter);
}
具体来说,如何在函数级别实现静态成员,而不是在类级别?将函数放入类中会改变什么吗?
这个C/ c++代码在Python中的等效代码是什么?
void foo()
{
static int counter = 0;
counter++;
printf("counter is %d\n", counter);
}
具体来说,如何在函数级别实现静态成员,而不是在类级别?将函数放入类中会改变什么吗?
当前回答
全局声明提供此功能。在下面的例子中(python 3.5或更高版本使用“f”),counter变量在函数外部定义。在函数中将其定义为全局的,意味着函数外部的“全局”版本应该对函数可用。所以每次函数运行时,它都会修改函数外部的值,在函数外部保留它。
counter = 0
def foo():
global counter
counter += 1
print("counter is {}".format(counter))
foo() #output: "counter is 1"
foo() #output: "counter is 2"
foo() #output: "counter is 3"
其他回答
其他答案已经演示了您应该如何做到这一点。这里有一种方法你不应该:
>>> def foo(counter=[0]):
... counter[0] += 1
... print("Counter is %i." % counter[0]);
...
>>> foo()
Counter is 1.
>>> foo()
Counter is 2.
>>>
默认值仅在函数第一次求值时初始化,而不是每次执行时初始化,因此可以使用列表或任何其他可变对象来存储静态值。
def staticvariables(**variables):
def decorate(function):
for variable in variables:
setattr(function, variable, variables[variable])
return function
return decorate
@staticvariables(counter=0, bar=1)
def foo():
print(foo.counter)
print(foo.bar)
就像上面vincent的代码一样,这将被用作函数装饰器,静态变量必须以函数名作为前缀访问。这段代码的优点(尽管每个人都可以聪明地看出这一点)是你可以有多个静态变量,并以更常规的方式初始化它们。
另一个(不推荐!)对https://stackoverflow.com/a/279598/916373这样的可调用对象的扭曲,如果您不介意使用一个时髦的调用签名的话
class foo(object):
counter = 0;
@staticmethod
def __call__():
foo.counter += 1
print "counter is %i" % foo.counter
>>> foo()()
counter is 1
>>> foo()()
counter is 2
_counter = 0 def foo(): global _counter _counter += 1 print 'counter is', _counter
Python习惯上使用下划线来表示私有变量。在C语言中,在函数内部声明静态变量的唯一原因是将它隐藏在函数之外,这并不是真正的Python惯用方法。
你也可以考虑:
def foo():
try:
foo.counter += 1
except AttributeError:
foo.counter = 1
推理:
非常python化(“请求原谅而不是允许”) 使用异常(只抛出一次)而不是if分支(考虑StopIteration异常)