Python中的私有方法
Python中没有像许多其他语言那样的“私有”概念。它建立在“成年人自愿原则”的基础上,即代码的用户将负责地使用它。按照约定,以单个或双下划线开头的属性将被视为内部实现的一部分,但它们实际上并不对用户隐藏。双下划线会导致属性名称的名称修改。
同时,需要注意的是,self
仅仅是一种约定,而不是语言本身的特性。当作为实例的成员调用实例方法时,会隐式地将实例作为第一个参数传递,但在方法的实现中,该参数实际上可以被任意命名。self
只是一种便于理解代码的约定。因此,如果在方法的签名中不包含self
,除了导致隐式实例参数被赋值给签名中的下一个变量名之外,没有任何实际功能上的效果。
当然,这对于类方法来说是不同的,类方法会接收类对象的实例作为隐式的第一个参数,而静态方法则根本不接收隐式参数。
在Python中,所有的方法和属性都是公有的,即可以在类的外部访问。然而,有时候我们希望某些方法和属性只能在类的内部使用,这就是私有方法和属性的概念。
在上述代码中,作者演示了一种实现私有方法和属性的不推荐的方法。首先,定义了一个内部类`SneakyCounterInternal`,其中包含了需要私有化的方法和属性。然后,定义了一个外部类`SneakyCounterExternal`,该类只是作为内部类的接口,可以通过该类的实例来间接调用内部类的方法。最后,通过返回外部类的实例,实现了对内部类方法的访问。
虽然上述方法可以实现私有方法和属性,但不推荐使用。Python的设计哲学是"we are all consenting adults here",即相信开发者的自律。因此,正常情况下不需要使用私有方法和属性。如果确实有需要,可以通过在方法或属性名前加上一个下划线来表示它是私有的,这是一种约定俗成的做法。
总之,Python中不存在真正的私有方法和属性,但可以通过一些编码约定和技巧来模拟实现。然而,这种模拟实现并不推荐使用,因为它违背了Python的设计哲学。我们应该尽量遵循Python的惯例和约定,以提高代码的可读性和可维护性。
在Python中,没有私有方法或属性的概念。这完全取决于你如何实现你的类。但是你可以使用伪私有变量(名称改编);任何以__
(两个下划线)开头的变量都变成了伪私有变量。
根据文档:
由于类私有成员有一个有效的用例(即避免与子类定义的名称冲突),所以有对这种机制的有限支持,称为名称改编。任何形式为
__spam
(至少两个前导下划线,最多一个尾部下划线)的标识符将在文本上被替换为_classname__spam
,其中classname是当前类名去掉前导下划线后的部分。这种改编不考虑标识符的句法位置,只要它出现在类的定义内部即可。
class A: def __private(self): pass
所以__private
现在实际上变成了_A__private
。
静态方法的示例:
>>> class A: ... # 在Python 3.x中不需要 ... def __private(): ... print('hello') ... >>> A._A__private() hello
我可以只写def __private(): pass
而不需要self吗?然后在我的类中调用它__private()。我可以在类外部访问这个函数吗?
如果你将它定义为静态方法,然后调用它:A._A__private()
这种情况下的静态是什么意思?
__
的目标是避免与子类冲突。它通过名称改编来实现,将类名合并到变量中。这使得变量更难以找到和访问,这是一个副作用。
静态意味着你可以将其作为普通函数使用,不需要传递实例。
我认为在我的情况下不需要一个装饰器。我不打算将它与任何实例关联起来。它就像是一个内部工作在类中使代码更紧凑和模态的服务函数,因为我在类的许多其他方法中使用它。
你确实需要一个装饰器。Python特殊处理类方法的第一个参数,所以除非你应用@staticmethod
或类似的装饰器,否则你会得到一个错误。
Python 3文档更新:docs.python.org/3/tutorial/classes.html#tut-private