2014-01-22 102 views
2

在Python方法中,我想要一个局部变量,其值在调用方法之间保持不变。python方法中的静态变量

This question显示了如何在函数内声明这样的“静态变量”(C++术语)。我尝试在实例方法中执行相同的操作,但失败了。

下面是一个可以重现问题的简单示例。您可以将其复制粘贴到解释器中。

class SomeClass(object): 
    def some_method(self): 
     if not hasattr(SomeClass.some_method, 'some_static_var'): 
      SomeClass.some_method.some_static_var = 1 # breaks here 

     for i in range(3): 
      print SomeClass.some_method.some_static_var 
      SomeClass.some_method.some_static_var += 1 

if __name__ == '__main__': 
    some_instance = SomeClass() 
    some_instance.some_method() 

上标有 “#符这里” 行了,我得到:

AttributeError: 'instancemethod' object has no attribute 'some_static_var'

我知道有一个简单的解决办法,我在那里做some_static_varSomeClass一个成员变量。然而,这个变量在这个方法之外确实没有用处,所以如果可以的话,我宁愿让它免于混淆SomeClass的命名空间。

+0

什么'SomeClass的。 some_method.im_func.some_static_var = 1'(假设python2) –

回答

1

在python 2中,你必须处理绑定和未绑定的方法。这些没有__dict__属性,如功能做:

#python 2 
'__dict__' in dir(SomeClass.some_method) 
Out[9]: False 

def stuff(): 
    pass 

'__dict__' in dir(stuff) 
Out[11]: True 

在Python 3,你的代码工作正常!绑定/非绑定方法的概念消失了,所有东西都是一个函数。

#python 3 
'__dict__' in dir(SomeClass.some_method) 
Out[2]: True 

回让你的代码工作,你需要把属性上具有__dict__的东西:实际功能:

if not hasattr(SomeClass.some_method.__func__, 'some_static_var'): 
    #etc 

Read more on im_func and __func__ here

它是由你来决定这是否让你的代码更具可读性 - 对我来说,制作这些类的东西几乎总是要走的;没有关系,只有一种方法访问所述属性,这是我寻找“静态”类型变量的地方。我重视干净的命名空间的可读代码。

这最后一段是当然的社论中,每个人都有权表达他们的观点:-)

1

您不能设置方法的对象属性。

创建属性改为(即SomeClass.some_var = 1)是标准的Python方式。但是,如果您能够对您的实际问题进行高级别概述(我们为此编写了哪些代码?),我们可能会提出更适合的修复方案。

+0

他可以将属性放在实际的函数上,而不是包装的方法对象。 –

-1

使用global关键字来访问文件级变量

my_static = None 

class MyClass(object): 
    def some_method(self): 
     global my_static 
     if my_static is None: 
      my_static = 0 
     else: 
      my_static = my_static + 1 
     print my_static 

if __name__ == '__main__': 
    instance = MyClass() 
    instance.some_method() 
    instance.some_method() 

输出:

0 
1 

虽然,正如其他地方提到,类变量将是可取的