【问题标题】:static variables inside a python methodpython方法中的静态变量
【发布时间】:2026-02-12 23:30:01
【问题描述】:

在 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()

在标有“#break here”的行上,我得到:

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

我意识到有一个简单的解决方法,我将some_static_var 设为SomeClass 的成员变量。但是,该变量在方法之外确实没有任何用处,所以如果可以的话,我更希望避免它弄乱SomeClass' 命名空间。

【问题讨论】:

  • SomeClass.some_method.im_func.some_static_var = 1 怎么样(假设是 python2)

标签: python methods static static-variables


【解决方案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

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

最后一段当然是社论,每个人都有权发表自己的意见:-)

【讨论】:

    【解决方案2】:

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

    创建 class 属性(即SomeClass.some_var = 1)是标准的 Python 方式。但是,如果您对您的实际问题进行简要概述(您编写此代码的目的是什么?),我们可能会提出更合适的修复建议。

    【讨论】:

    • 他可以将属性放在实际的函数上,而不是包装的方法对象上。
    【解决方案3】:

    使用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
    

    尽管如其他地方所述,类变量更可取

    【讨论】: