这个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);
}
具体来说,如何在函数级别实现静态成员,而不是在类级别?将函数放入类中会改变什么吗?
当前回答
你也可以考虑:
def foo():
try:
foo.counter += 1
except AttributeError:
foo.counter = 1
推理:
非常python化(“请求原谅而不是允许”) 使用异常(只抛出一次)而不是if分支(考虑StopIteration异常)
其他回答
其他答案已经演示了您应该如何做到这一点。这里有一种方法你不应该:
>>> def foo(counter=[0]):
... counter[0] += 1
... print("Counter is %i." % counter[0]);
...
>>> foo()
Counter is 1.
>>> foo()
Counter is 2.
>>>
默认值仅在函数第一次求值时初始化,而不是每次执行时初始化,因此可以使用列表或任何其他可变对象来存储静态值。
有点相反,但这应该是有效的:
def foo():
foo.counter += 1
print "Counter is %d" % foo.counter
foo.counter = 0
如果你想让计数器初始化代码在顶部而不是底部,你可以创建一个装饰器:
def static_vars(**kwargs):
def decorate(func):
for k in kwargs:
setattr(func, k, kwargs[k])
return func
return decorate
然后像这样使用代码:
@static_vars(counter=0)
def foo():
foo.counter += 1
print "Counter is %d" % foo.counter
它仍然需要你使用foo。前缀,不幸的是。
(图片来源:@ony)
_counter = 0 def foo(): global _counter _counter += 1 print 'counter is', _counter
Python习惯上使用下划线来表示私有变量。在C语言中,在函数内部声明静态变量的唯一原因是将它隐藏在函数之外,这并不是真正的Python惯用方法。
Python方法中的静态变量
class Count:
def foo(self):
try:
self.foo.__func__.counter += 1
except AttributeError:
self.foo.__func__.counter = 1
print self.foo.__func__.counter
m = Count()
m.foo() # 1
m.foo() # 2
m.foo() # 3
这个回答建立在@claudiu的回答之上。
我发现我的代码变得越来越不清晰,而我一直都很清楚 当我要访问静态变量时,可以在函数名前面加上。
也就是说,在我的函数代码中,我更喜欢这样写:
print(statics.foo)
而不是
print(my_function_name.foo)
所以,我的解决方案是:
向函数中添加静态属性 在函数作用域中,添加一个局部变量statics作为my_function.statics的别名
from bunch import *
def static_vars(**kwargs):
def decorate(func):
statics = Bunch(**kwargs)
setattr(func, "statics", statics)
return func
return decorate
@static_vars(name = "Martin")
def my_function():
statics = my_function.statics
print("Hello, {0}".format(statics.name))
备注
我的方法使用一个名为Bunch的类,它是一个字典,支持 属性风格的访问,一种JavaScript(参见2000年左右关于它的原始文章)
它可以通过pip install bunch安装
也可以这样手写:
class Bunch(dict):
def __init__(self, **kw):
dict.__init__(self,kw)
self.__dict__ = self