簡體   English   中英

python方法內的靜態變量

[英]static variables inside a python method

在Python方法中,我想要一個局部變量,該局部變量的值在調用該方法之間保持不變。

這個問題說明了如何在函數內部聲明這種“靜態變量”(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 here”的行上,我得到:

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

我意識到有一個簡單的解決方法,可以將some_static_var SomeClass的成員變量。 但是,該變量實際上在方法之外沒有任何用處,因此,如果可以的話,我更希望避免使該變量混亂SomeClass '命名空間。

在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

在此處閱讀有關im_func__func__更多信息

由您來決定這是否使您的代碼更具可讀性-對我來說,使這些類型的事情具有類屬性幾乎總是要走的路。 不管是哪種方法都可以訪問所述屬性,這是我尋找“靜態”類型vars的地方。 我重視可讀代碼,而不是干凈的命名空間。

最后一段當然是社論,每個人都有自己的見解:-)

您不能在方法對象上設置屬性。

相反,創建屬性(即SomeClass.some_var = 1 )是標准的Python方法。 但是,如果您向我們提供有關實際問題的高級概述(您打算將此代碼編寫的目的是什么?),我們可能會提出更合適的解決方案。

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

盡管,如其他地方所述,最好使用類變量

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM