搜尋

首頁  >  問答  >  主體

python2.7 - python 函數或類別 程式碼的執行順序

修改了一下問題,大家直接先看範例 3

對於簡單的控制語句來說,

x = 1
if x > 0:
    print('true')
else:
    print('false')

我們都知道當判定 x > 0時,else的語句是不會執行的,

python 屬於解釋型語言,對於函數來講,例1

# filename test.py

def test1():
    pass
    
# test1()

以下是我不知道正確與否的理解:

1,對於java而言,如果沒有對於test1() 這一行程式碼執行對函數test1 的呼叫的話,那就整個程式基本上沒有意義,不會有記憶體分配,也不會有執行
2,但是對於python 而言,會創建test1 函數對象,然後保存test1 中的一系列操作,這些操作不會被執行,即使整個程序沒有對test1 有任何的調用操作,但是只要程序沒有結束,那麼test1就會一直存在於記憶體中。
至於原因,是函數 test1 在程式執行後,會成為目前模組對象,也就是 module __main__ 的屬性。
3,而對於 ‘test1’ 這個函數名稱而言,他引用了這個函數對象,所以就算沒有呼叫該函數,垃圾回收機制不會將其回收

巢狀函數 例2

# filename test.py

def test1():
    def test2():
        pass
    # return test2()
    
# test1()

對於例 1,我的理解有錯誤嗎?

對比例 2 中 test1 的內層函數 test2 的情況是怎麼樣的,有呼叫和沒有呼叫的情況會有什麼不同嗎?

之前問題可能描述的不太清楚,這兒再舉一個例子 3

>>> class A(object):
    a = []

    def test1(self):
        pass
    
    @classmethod
    def test2(cls):
        print('cls.a', sys.getrefcount(cls.a))
        print('cls.test1:', sys.getrefcount(cls.test1))

        
>>> A.test2()
('cls.a', 2)
('cls.test1:', 1)

上面的輸出這個 2 可以理解,但是為什麼另一個是 1 呢?

>>> def test3():
    def test4():
        pass

    
>>> sys.getrefcount(test3)
2
>>> dir(test3)
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']

# sys.getrefcount(test4)    NameError: name 'test4' is not defined

現在的問題是 test3 中的內層函數 test4 在記憶體中嗎?如果在的話,在哪裡? (我覺得是應該在記憶體中的)如果沒在的話,為什麼沒有 test4?如果沒有 test4 的話,修改一下上面的程式碼又該怎麼看 ?

def test3():
    def test4():
        pass
    return test4   # return test4()
剛剛修改了問題的時候,突然想到對於程式設計來講可能沒什麼實際意義,大家可能都會知道怎麼去定義使用內層函數。但我還是希望有人能解答我的問題
習慣沉默習慣沉默2726 天前794

全部回覆(1)我來回復

  • PHP中文网

    PHP中文网2017-06-12 09:27:49

    建議以後這問題拆成兩個不同問題。
    (1)沒有呼叫該函數, Python還有另一個記憶體管理策略reference counting:「原理: 記錄一個物件被其他物件引用的次數. 當對這個物件的引用移除了, 引用計數也減小了.要是減到0了, 這個物件也就被釋放了」。所以我猜,應該是在reference counting 時已經回收了。

    (2)有沒有呼叫就是看某個物件的參考是否移除了,還有是否有reference cycle,這裡的郵件討論串有一個類近的討論,不知道算不算回答了你這個問題。

    回覆
    0
  • 取消回覆