2011-08-24 49 views
1

說我有一個1 MB的文本文件。考慮下面的例子:python內存問題

class A: 

    def __init__(self, file): 
     self.file = file 

class B: 

    def __init__(self, file): 
     self.a = A(file) 

f = open(path, 'r') 
file = f.read() 
f.close() 

x = B(file) 

我創建兩個文件,因此浪費兩兆字節,而不是1?或者python識別文件對象,並給出原始文件的引用?

邊問:是不是更好地在這種情況下使用全局變量?

回答

4

的Python通過引用傳遞參數,所以基本上是「字符串」你進入B()實際上是一個指針(存儲器地址),以實際的字符串。如果您在執行示例腳本時查看每個對象,您會發現它們都是一樣的。

例如,這個版本打印傳遞的對象(使用object.__repr__因爲str.__repr__打印數據)的repr()

class A: 
    def __init__(self, f): 
     print(repr(self), "received", object.__repr__(f)) 
     self.f = f 


class B: 
    def __init__(self, f): 
     print(repr(self), "received", object.__repr__(f)) 
     self.a = A(f) 



with open(LARGE_FILE, 'rb') as f: 
    text = f.read() 

print("passing", object.__repr__(f), "into B()") 
x = B(text) 

結果是這樣的:

passing <str object at 0x280f960> into B() 
<__main__.B object at 0x290acd0> received <str object at 0x280f960> 
<__main__.A object at 0x290add0> received <str object at 0x280f960> 

正如你所看到的,當字符串變量傳遞給構造函數A()B()時,它是相同的對象:實際上是一個指向字符串的指針。

這很少消耗額外的內存。

1

您只傳遞參考。沒有浪費的記憶。

3

您正在閱讀的文件一次,所以它的內容存儲在內存中一次。會發生什麼是:

  • 該文件內容被讀入並且被稱爲file;
  • 將參考傳遞給B初始值設定項;
  • 通過對A初始值設定項的引用;
  • 存儲參考;
  • 初始化器返回對它們創建的對象的引用。

認識到Python總是通過引用傳遞參數並返回值很重要。 Python中的變量只是對象的名稱,而不是存儲位置。

1
  1. 不,Python與引用一起工作,所以在您的示例中只有一個文件數據對象。

  2. 全局變量應該儘量避免,只要有可能這樣做。只有在沒有其他選擇時才使用它們。

1

上午我創建了兩個文件,因此浪費了2兆字節,而不是1?

號事實上,擺在首位創建任何文件。

或者python能夠識別文件對象,並給出原始文件的引用嗎?

在給定的例子中只傳遞了一個OS文件句柄的包裝器的引用。

支持問:在這種情況下使用全局變量更好嗎?

非也。

1

只是一個提示:你不應該使用文件作爲名稱,因爲它是一個Python中的函數。

你可以做

myfile=open('somepath','r') 

myfile=file('somepath','r') 

open是首選的方式。

其實我相信open()使用file()所以重新分配文件應該會產生一些奇怪的行爲。