Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用;“私人”;变量+;方法v.s.“;“公众”;实例变量_Python_Design Patterns - Fatal编程技术网

Python 使用;“私人”;变量+;方法v.s.“;“公众”;实例变量

Python 使用;“私人”;变量+;方法v.s.“;“公众”;实例变量,python,design-patterns,Python,Design Patterns,我经常看到这种模式: class Foo: def __init__(self, bar): self._bar = bar def bar(self): return _bar 为什么这比这更好 class Foo: def __init__(self, bar) self.bar = bar 它将条形图的外部表示形式与其内部表示形式解耦。在您的第一个代码中,出于某些原因,这有时更可取。首先,在Python中,

我经常看到这种模式:

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

    def bar(self):
        return _bar
为什么这比这更好

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

它将
条形图的外部表示形式与其内部表示形式解耦。

在您的第一个代码中,出于某些原因,这有时更可取。首先,在Python中,
\u name
只是一种命名约定,它向开发人员指出,
\u 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
              ...
\u wrap\u close
是调用
os.popen
\u proc
时返回的包装类。这不仅表明您不应该在代码中直接访问该属性,而且还可能表明该属性对于类的功能至关重要,如果您查看内部,
os.popen
您可能会看到原因:

# 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) 
\u wrap\u close
是一个围绕
Popen
返回的对象的包装类,实际上
\u wrap\u close
委托许多操作和访问
self.\u proc
<代码>\u wrap\u close
本身使用
\u name
命名约定

在某些情况下:

def bar(self):
    return self._bar

通常在返回
self.\u bar
之前会有一些处理和逻辑。也可以使用属性和描述符。不同的开发人员出于不同的原因使用不同的功能

这是针对Java的,但我认为它的精神仍然回答了您的问题。特别是在python中,因为在第一种情况下,如果不使用
self.\u bar
,就无法更改
bar
引用。在第二种情况下,一切皆有可能,变量的“保护”程度较低。@Jean Françoisfare我认为这最直接地回答了这个问题。使用方法的原因是,它可以保护引用不被更改(假设用户知道不要触摸
\u variables
),同时使值易于访问。不过,这只解释了问题的一半-当属性存在时,是否有任何理由使用方法?@得出的答案是,绝对没有!所以问题是问关于不使用这个词的属性——相当聪明@比尔:这就是你要找的吗?“通常在返回自我之前会有一些处理和逻辑。_bar”@direprobs我的问题是关于返回之前没有处理逻辑的情况。为什么要在这些情况下创建这个方法?@Bill你能给我们提供一个真实的例子吗?这里有一个例子:NLTK WordNet包中的类引理@direprobs@Bill在引入属性之前,开发人员似乎希望自己不受未来变化的影响,如果需要改变的话简单属性将来要做一些处理,而不是仅仅返回一个普通属性,更改为函数将很困难,因为这会破坏很多代码。我的猜测正确的可能性有多大?代码是用2.X编写的,这只是我所知道的。无论如何,不要激动自己!只需知道,
\u name
是一种表示对象内部属性的命名约定。