Python类中私有变量的实际实现

7 浏览
0 Comments

Python类中私有变量的实际实现

在阅读Python文档中关于私有变量的部分时,我遇到了一个问题。文档说明了用下划线命名私有变量是一种约定,但Python并没有使字段私有化。\n我想知道在Python中是否有一种方法可以使变量真正私有化。

0
0 Comments

在Python类中,可以使用双下划线来调用Python的名称混淆功能。因此,__priv将变为_MyClass__priv。尽管仍然可以访问它,但它可以防止子类意外覆盖。

当然,任何人都可以通过混淆后的名称访问它。

Python中的封装是通过使用单下划线或双下划线来实现的。使用单下划线表示这是一个内部变量,不应该被直接访问。而双下划线表示这是一个私有变量,应该被尽量避免直接访问。

然而,Python的私有变量并不是真正的私有,仍然可以通过名称混淆的方式来访问。这可能会导致一些问题,因为子类可能会意外地覆盖父类的私有变量,从而破坏了封装性。

为了解决这个问题,可以在私有变量前添加一个下划线作为前缀,以表示这是一个内部变量,不应该被直接访问。这样可以提醒开发者不要直接访问这个变量。另外,还可以使用名称混淆来防止子类意外覆盖父类的私有变量。

下面是一个示例代码,演示了如何实现私有变量和名称混淆:

class MyClass:
    def __init__(self):
        self._priv = "private variable"
    def _internal_method(self):
        print("Internal method")
    def public_method(self):
        self._internal_method()
        print(self._priv)
class SubClass(MyClass):
    def __init__(self):
        super().__init__()
        self._priv = "sub class private variable"
obj = MyClass()
obj.public_method()
sub_obj = SubClass()
sub_obj.public_method()

在上面的代码中,_priv被用作私有变量,并且以_作为前缀表示这是一个内部变量。而_internal_method被用作内部方法。

当调用public_method时,会调用_internal_method并打印私有变量_priv的值。

输出结果如下:

Internal method
private variable
Internal method
sub class private variable

通过这种方式,我们可以实现类似私有变量的封装,并使用名称混淆来防止子类意外地覆盖父类的私有变量,从而提高代码的封装性和可维护性。

0
0 Comments

Python中没有私有变量或方法。短语“我们都是成年人”通常用于解释它们被认为是不必要的。

有时候会使用单下划线表示“私有”成员,但这只是一种约定;它没有任何功能性的作用。

前导双下划线会导致名称改编,但它们只是用于避免子类中的命名冲突。它不提供任何“私有成员安全性”,因为仍然可以访问它们。

这些问题的出现是因为Python设计者认为在Python中,开发者应该有责任遵守约定,而不是通过限制访问来强制实现私有性。这种设计哲学强调了Python对开发者的信任,认为开发者应该能够自由地使用类的所有成员,而不受限制。

然而,有时候确实需要实现私有性,以避免意外访问或修改类的内部状态。在这种情况下,可以使用约定来表示私有成员,即使用单下划线作为前缀。这个约定告诉其他开发者,这个成员是私有的,不应该被直接访问或修改。虽然这只是一种约定,但大多数开发者会遵守它,以尊重类的设计意图。

另一种实现私有性的方法是使用前导双下划线作为前缀。这会导致名称改编,使得子类中的命名冲突得以避免。然而,这并不是真正的私有性,因为仍然可以通过特定的语法来访问这些成员。这种方法更多地用于避免命名冲突,而不是实现私有性。

Python中没有真正的私有变量或方法。开发者应该通过约定来表示私有成员,并相信其他开发者会遵守这个约定。如果确实需要实现私有性,可以使用前导双下划线来避免命名冲突,但仍然可以通过特定的语法来访问这些成员。

0
0 Comments

在Python类中实现私有变量的问题出现的原因是,Python开发人员认为成年人应该自行负责,即使有可能自己给自己带来麻烦。

解决这个问题的方法是,可以稍微隐藏私有变量,但实际上不应该这样做。一个解决办法是使用双下划线(__)作为私有变量的前缀,这将使变量在类外部无法直接访问。然而,仍然可以通过一些技巧绕过这一限制,例如使用`__getattr__`方法来动态获取私有变量。但是,这种方法并不推荐使用,因为违背了Python的设计原则。

以下是一个例子,展示了如何尝试访问私有变量以及如何通过`__dict__`属性绕过限制:

class NonAdult(object):
    def __init__(self):
        self.__private_number = '42'
        
    def __getattr__(self, name):
        if name.startswith('__private'):
            raise AttributeError
if __name__ == '__main__':
    na = NonAdult()
    print(na.__private_number) # raises AttributeError
    print(na.__dict__['_NonAdult__private_number']) # would still return 42

通过`__dict__`属性可以访问到私有变量`__private_number`的值,但实际上这并不是一种推荐的做法。

Python中实现私有变量的方法并不是真正意义上的私有,开发人员应该遵循Python的设计原则,避免使用私有变量。

0