[英]Private methods in Python
我想在我的类中有一个函数,我将只在这个类的方法中使用它。 我不会在这些方法的实现之外调用它。 在 C++ 中,我会使用在类的私有部分中声明的方法。 在 Python 中实现这样一个函数的最佳方法是什么?
我正在考虑在这种情况下使用静态装饰器。 我可以使用没有任何装饰器和self
词的函数吗?
Python 没有私有方法或属性的概念。 这完全取决于您如何实现您的课程。 但是您可以使用伪私有变量(名称修改); 任何以__
(两个下划线)开头的变量都成为伪私有变量。
从文档中:
由于类私有成员有一个有效的用例(即避免名称与子类定义的名称发生名称冲突),因此对这种称为名称修饰的机制的支持有限。
__spam
形式的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为_classname__spam
,其中 classname 是当前类名,前导下划线被剥离。 只要它出现在类的定义中,就无需考虑标识符的句法位置,就可以完成这种修饰。
class A:
def __private(self):
pass
所以__private
现在实际上变成_A__private
。
静态方法示例:
>>> class A:
... @staticmethod #not required in py3.x
... def __private():
... print 'hello'
...
>>> A._A__private()
hello
Python 不像许多其他语言那样具有“私有”的概念。 它建立在同意成人原则的基础上,即您的代码的用户将负责任地使用它。 按照惯例,以单下划线或双下划线开头的属性将被视为内部实现的一部分,但它们实际上并未对用户隐藏。 但是,双下划线会导致属性名称的名称混乱。
另外,请注意self
仅按惯例是特殊的,而不是语言的任何特性。 实例方法,当作为实例的成员调用时,会隐式地将实例作为第一个参数传递,但在方法本身的实现中,从技术上讲,该参数可以命名为您想要的任何任意事物。 self
只是为了便于理解代码的约定。 因此,在方法的签名中不包括self
没有实际的功能影响,只会导致将隐式实例参数分配给签名中的下一个变量名。
这对于类方法当然是不同的,它接收类对象本身的实例作为隐式的第一个参数,而静态方法则根本不接收任何隐式参数。
这里有很多很棒的东西,使用前导下划线进行混淆。 就个人而言,我从语言设计决策中受益匪浅,因为它减少了理解和使用新模块所需的时间。
但是,如果您决心实现私有属性/方法并且您愿意成为 unpythonic,您可以执行以下操作:
from pprint import pprint
# CamelCase because it 'acts' like a class
def SneakyCounter():
class SneakyCounterInternal(object):
def __init__(self):
self.counter = 0
def add_two(self):
self.increment()
self.increment()
def increment(self):
self.counter += 1
def reset(self):
print 'count prior to reset: {}'.format(self.counter)
self.counter = 0
sneaky_counter = SneakyCounterInternal()
class SneakyCounterExternal(object):
def add_two(self):
sneaky_counter.add_two()
def reset(self):
sneaky_counter.reset()
return SneakyCounterExternal()
# counter attribute is not accessible from out here
sneaky_counter = SneakyCounter()
sneaky_counter.add_two()
sneaky_counter.add_two()
sneaky_counter.reset()
# `increment` and `counter` not exposed (AFAIK)
pprint(dir(sneaky_counter))
很难想象您想要这样做的情况,但这是可能的。
Python 只是不做私有的。 如果您愿意,您可以遵循约定并在名称前加上一个下划线,但其他编码人员必须以绅士的方式尊重这一点†
† 或绅士风度
你只是不这样做:
Pythonic 方法是不使用docstrings记录这些方法/成员,仅使用“真实”代码注释。 约定是在它们后面加上一个或两个下划线;
然后你可以在你的成员前面使用双下划线,这样它们就成为类的本地(主要是名称修饰,即类外成员的真实名称变为: instance.__classname_membername
)。 在使用继承时避免冲突或在类的子级之间创建“私有空间”很有用。
据我所知,可以使用元类“隐藏”变量,但这违反了 Python 的整个哲学,所以我不会对此进行详细介绍。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.