2017-06-22 159 views
0

我常常看到這樣的圖案:使用「私人」變量+方法v.s. 「公共」的實例變量

class Foo: 
    def __init__(self, bar): 
     self._bar = bar 

    def bar(self): 
     return _bar 

爲什麼那會是最好的?

class Foo: 
    def __init__(self, bar) 
     self.bar = bar 
+3

這是爲Java,但我認爲它的精神仍然回答你的問題[爲什麼使用getters和setters?](https://stackoverflow.com/questions/1568091/why-use-getters-and-setters) 。具體來說,[見'@ property'](https://stackoverflow.com/questions/6618002/python-property-versus-getters-and-setters) – CoryKramer

+1

因爲你不能改變'bar'的引用而不使用'self。 _bar'在第一種情況下。在第二種情況下,任何事情都是可能的,變量不太「受保護」。 –

+0

@ Jean-FrançoisFabre我認爲這直接回答了這個問題。使用方法的原因是它可以保護引用不被修改(假設用戶知道不要觸摸'_variables'),同時可以輕鬆訪問該值。 – Bill

回答

0

在你的第一個代碼中,這有時會因爲某些原因而更可取。首先,Python _name只是一個命名約定,它向開發人員表明_name不應該從其定義的位置以外的位置訪問,無論是類,模塊還是其他類型。這種命名約定還有助於避免名稱衝突,特別是如果屬性在功能方面至關重要。

讓我們用真實的例子來演示。你會發現,這些例子很多os.py模塊中,例如:

# Helper for popen() -- a proxy for a file whose close waits for the process 
class _wrap_close: 
    def __init__(self, stream, proc): 
     self._stream = stream 
     self._proc = proc 
       ... 

_wrap_close是當你調用os.popen這所返回的包裝類。 _proc。這不僅表明你不應該直接在你的代碼中訪問它,而且可能表明這個屬性對於這個類的功能是至關重要的,如果你仔細看看,你可能會看到爲什麼:

# Supply os.popen() 
def popen(cmd, mode="r", buffering=-1): 
    # many code omitted here... 
    if mode == "r": 
     proc = subprocess.Popen(cmd, 
           shell=True, 
           stdout=subprocess.PIPE, 
           bufsize=buffering) 
     return _wrap_close(io.TextIOWrapper(proc.stdout), proc) 
    # many code omitted here... (see os.py) 

_wrap_close是通過周圍和Popen事實上_wrap_close代表許多操作返回的對象的包裝類和訪問self._proc_wrap_close本身使用_name命名約定。

在一些情況下:

def bar(self): 
    return self._bar 

通常會有一些處理和邏輯返回self._bar之前。也可以使用屬性和描述符。不同的開發者出於不同的原因使用不同的功能

+0

@Bill這是你在找什麼? – direprobs

+0

「通常在返回self之前會有一些處理和邏輯._bar」 @direprobs我的問題具體是關於在返回之前沒有處理邏輯的情況。爲什麼在這些情況下創建方法? – Bill

+0

@Bill您能否爲我們提供一個您遇到過這個問題的真實例子? – direprobs

0

它將bar的外部表示從其內部表示中解除耦合。

+3

這隻解釋了一半的問題,但是 - 有什麼理由在屬性存在時使用方法嗎? –

+1

@回答這個問題,重點不是! –

+1

所以問題是詢問關於使用這個詞的屬性w/o - 非常聰明! –