kus*_*men 11 python python-3.x
在C++中我们有静态关键字,在循环中是这样的:
for(int x=0; x<10; x++)
{
for(int y=0; y<10; y++)
{
static int number_of_times = 0;
number_of_times++;
}
}
Run Code Online (Sandbox Code Playgroud)
这里静态number_of_times初始化一次.我怎么能在python 3.x中做同样的事情?
编辑:由于大多数人感到困惑,我想指出我给出的代码只是C++静态用法的一个例子.我真正的问题是我想在函数中只初始化一个时间变量,因为我不希望它是全局的(等等!)或默认参数..
bru*_*ers 23
假设你想要的是"一个在第一次函数调用时只初始化一次的变量",那么在Python语法中就没有这样的东西了.但有一些方法可以获得类似的结果:
1 - 使用全局.请注意,在Python中,"全局"实际上意味着"模块的全局",而不是"流程的全局":
_number_of_times = 0
def yourfunc(x, y):
global _number_of_times
for i in range(x):
for j in range(y):
_number_of_times += 1
Run Code Online (Sandbox Code Playgroud)
2 - 将代码包装在类中并使用类属性(即:所有实例共享的属性).:
class Foo(object):
_number_of_times = 0
@classmethod
def yourfunc(cls, x, y):
for i in range(x):
for j in range(y):
cls._number_of_times += 1
Run Code Online (Sandbox Code Playgroud)
请注意,我使用了一个,classmethod因为此代码段不需要实例中的任何内容
3 - 将代码包装在类中,使用实例属性并为方法提供快捷方式:
class Foo(object):
def __init__(self):
self._number_of_times = 0
def yourfunc(self, x, y):
for i in range(x):
for j in range(y):
self._number_of_times += 1
yourfunc = Foo().yourfunc
Run Code Online (Sandbox Code Playgroud)
4 - 编写可调用类并提供快捷方式:
class Foo(object):
def __init__(self):
self._number_of_times = 0
def __call__(self, x, y):
for i in range(x):
for j in range(y):
self._number_of_times += 1
yourfunc = Foo()
Run Code Online (Sandbox Code Playgroud)
4 bis - 使用class属性和元类
class Callable(type):
def __call__(self, *args, **kw):
return self._call(*args, **kw)
class yourfunc(object):
__metaclass__ = Callable
_numer_of_times = 0
@classmethod
def _call(cls, x, y):
for i in range(x):
for j in range(y):
cls._number_of_time += 1
Run Code Online (Sandbox Code Playgroud)
5 - 对模块导入时仅实例化一次的函数默认参数进行"创造性"使用:
def yourfunc(x, y, _hack=[0]):
for i in range(x):
for j in range(y):
_hack[0] += 1
Run Code Online (Sandbox Code Playgroud)
还有一些其他可能的解决方案/黑客攻击,但我认为你现在可以了解大局.
编辑:给出操作的澄清,即"让我们说你有一个带有默认参数的递归函数,但如果有人真的试图给你的函数多一个参数它可能是灾难性的",它看起来像OP真正想要的是:
# private recursive function using a default param the caller shouldn't set
def _walk(tree, callback, level=0):
callback(tree, level)
for child in tree.children:
_walk(child, callback, level+1):
# public wrapper without the default param
def walk(tree, callback):
_walk(tree, callback)
Run Code Online (Sandbox Code Playgroud)
哪,BTW,证明我们真的有另一个XY问题......
您可以创建一个闭包nonlocal以使其可编辑(仅限 python 3.x)。这是计算列表长度的递归函数的示例。
def recursive_len(l):
res = 0
def inner(l2):
nonlocal res
if l2:
res += 1
inner(l2[1:])
inner(l)
return res
Run Code Online (Sandbox Code Playgroud)
或者,您可以为函数本身分配一个属性。使用这里的技巧:
def fn(self):
self.number_of_times += 1
fn.func_defaults = (fn,)
fn.number_of_times = 0
fn()
fn()
fn()
print (fn.number_of_times)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27644 次 |
| 最近记录: |