前言:
在Python中,不像一些其他编程语言如Java或C++,并没有严格意义上的“私有”函数。不过,Python有一种约定俗成的做法来指示一个函数是私有的,这意味着它不应该被外部访问。
在Python中,如果你想定义一个私有函数,你可以在函数名称前加上两个下划线__。这会触发一个名字改编(name mangling)的过程,使得这个函数在外部不容易被直接访问。这种机制的目的是为了“伪私有”,实际上是提供了一种弱保护措施来避免子类意外覆盖基类的方法。
1 举例:
#!/usr/bin/env python
# coding=utf-8
"""
# @Time : 2024/4/7 8:25
# @Author : Summer
# @File : test.py
# @describe:
"""
class MyClass:
def __init__(self):
# 公有变量
self.public_var = 'I am public!'
# 私有变量
self.__private_var = 'I am private!'
def public_method(self):
return 'This is a public method!'
def __private_method(self):
return 'This is a private method!'
# 创建实例
obj = MyClass()
# 访问公有方法
print(obj.public_method()) # 输出: This is a public method!
# 无法直接访问私有方法,下面的代码会抛出AttributeError
# print(obj.__private_method()) # 报错
# 然而,通过一个改编后的名称,还是可以访问到这个所谓的“私有”方法
# 注意:这种方法不应被使用,因为它依赖于Python内部的实现细节,并且被视为不好的实践
print(obj._MyClass__private_method()) # 输出: This is a private method!
1.1 单下划线和双下划线定义:
在Python中,单下划线和双下划线在命名变量和方法时有特定的含义,它们被用来表明成员变量和方法的访问权限。以下分别解释了这两种用法:
单下划线(_)
单下划线前缀的成员变量或方法在Python中不是真正意义上的私有,它更多是一个约定,表明这些变量和方法主要用于内部使用,你不应该在类外部直接访问它们。不过,它们仍然是可以从外部访问的,并没有像双下划线那样对名称进行改编。
#!/usr/bin/env python
# coding=utf-8
"""
# @Time : 2024/4/7
# @Author : Summer
# @File : test.py
# @describe:
"""
class MyClass:
def _internal_method(self):
return "This is an internal method."
def public_method(self):
return "This method is public and can call the internal method."
_internal_variable = "This is an internal variable."
obj = MyClass()
# 通常不建议从外部直接访问单下划线的变量或方法,但技术上是可以的
print(obj._internal_method()) # 输出: This is an internal method.
print(obj._internal_variable) # 输出: This is an internal variable.
# 推荐的方式是通过一个公有方法访问
print(obj.public_method()) # 输出: This method is public and can call the internal method.
在实例obj中,虽然我们能访问_internal_method和_internal_variable,但是根据Python社区的约定,其他程序应该尽量避免直接访问以单下划线开始的变量或方法。
双下划线(__)
双下划线前缀的变量或方法是Python中一种弱“私有”机制,意味着它们在外部不容易被访问。当你在变量或方法名前加上双下划线时,Python会对这些名称进行改编(name mangling),在名称前加上单下划线和类名来避免与子类中的名称冲突。
#!/usr/bin/env python
# coding=utf-8
"""
# @Time : 2024/4/7
# @Author : Summer
# @File : test.py
# @describe:
"""
class MyClass:
def __private_method(self):
return "This is a private method."
def public_method(self):
# 可以在类内部调用私有方法
return f"This method is public and can call the private method: {self.__private_method()}"
__private_variable = "This is a private variable."
obj = MyClass()
# 直接从外部访问双下划线开头的私有变量或方法会导致错误
# print(obj.__private_method()) # 报错,找不到 __private_method
# print(obj.__private_variable) # 报错,找不到 __private_variable
# 通过公有方法间接访问
print(obj.public_method()) # 输出: This method is public and can call the private method: This is a private method.
# 通过改编后的名称访问,不过这种做法是不推荐的
print(obj._MyClass__private_variable) # 输出: This is a private variable.
print(obj._MyClass__private_method()) # 输出: This is a private method.
总结:
单下划线 _ 用作内部使用的变量或方法名称的前缀,是按照约定来的,但不会阻止外部访问。
双下划线 __ 的变量或方法是Python的一种弱私有机制,可通过名称改编来限制外部直接访问。
极力推荐按照约定来使用单下划线和双下划线,以遵循Python的惯例,并编写出更容易理解和维护的代码。
尽管通过名字改编你可以访问到这些所谓的私有成员,但是你不应该这么做,因为这与在类设计上规定的封装原则相违背。私有方法和变量应该仅在类的内部使用,不应该被外部访问。通过这种方式,你可以控制类的状态和行为,防止外部直接修改或依赖于类的内部实现细节。
总之,Python的私有成员实际上是依赖于开发者之间的约定,而不是由语言本身强制执行的。当你在命名一个方法时以双下划线__开始,你是在向其他开发者发送一个信息,表明这个方法或变量是内部使用的,不应该在类的外部被调用或访问。