2017-06-22 163 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 - 非常聪明! –