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
是一种表示对象内部属性的命名约定。