【拓展】 python3中类的重点与难点:类继承中的私有属性和私有方法

2022-10-21 09:57:27
私有属性、方法——Python并没有真正的私有化支持,但可用下划线得到伪私有

尽量避免定义以下划线开头的变量

   (1)xxx  公有变量

(2)_xxx      "单下划线 " 开始的成员变量叫做保护变量,意思是只有类对象(即类实例)和子类对象自己能访问到这些变量,需通过类提供的接口进行访问;不能用'from module import *'导入

   (3)__xxx    类中的私有变量/方法名 (Python的函数也是对象,所以成员方法称为成员变量也行得通。)," 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。

    (4)__xxx__ 系统定义名字,前后均有一个“双下划线” 代表python里特殊方法专用的标识,如 __init__() 代表类的构造函数。

实例解析

(1)公有变量不用多解释,就是可以公共访问的变量

(2)_xxx:前置单下划线的变量

privatization.py

num = 100
_num = 200
__num = 300

class Private(object):
    '''私有化'''
    def __init__(self):
        self.xxx = 'xxx'
        self._xxx = '_xxx'
        self.__xxx = '__xxx'

    def Get__xxx(self):
        return self.__xxx

不能用'from module import *'导入

In [1]: from privatization import *

In [2]: num
Out[2]: 100

In [3]: _num
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-3-a3b2dccd37c6> in <module>()
----> 1 _num

NameError: name '_num' is not defined

In [4]: __num
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-4-560eb7fca2ba> in <module>()
----> 1 __num

NameError: name '__num' is not defined

但是可以通过import module进行访问

In [6]: import privatization as p

In [7]: p.num
Out[7]: 100

In [8]: p._num
Out[8]: 200

In [9]: p.__num
Out[9]: 300

以下是通过'from module import *'导入的类对象访问的,所以可以直接的访问

from privatization import *

In [7]: private = Private()

In [8]: private.xxx
Out[8]: 'xxx'

In [9]: private._xxx
Out[9]: '_xxx'

(3)__xxx:前置双下划线私有变量

if __name__ == '__main__':
    private = Private()
    print(private.xxx)
    print(private._xxx)


    # __xxx:双前置下划线的私有属性,无法在外部直接访问(名字重整所以访问不到)
    #print(private.__xxx)

    # 因为python内部解释器将名字重整,所以报错为:AttributeError: 'Private' object has no attribute '__xxx'
    # 所以只要知道重整后的名字就可以直接访问
    #print(dir(private)) # 获取对象的所有属性和方法
    '''
    ['_Private__xxx', '__class__', '__delattr__', '__dict__', '__dir__', 
    '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
    '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__',
    '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
    '__subclasshook__', '__weakref__', '_xxx', 'xxx']
    '''
    # 可以看到python将名字重整为_类名__xxx, 所以可以通过改名字直接访问
    print(private._Private__xxx)


    # 也可以通过公有方法简介获取
    print(private.Get__xxx())

    # 如果在类中向__名字赋值,那么会在类中定义的一个与类相同名字的属性
    private.__xxx = 'new __xxx'
    print(private.__xxx)

总结

  • 父类中属性名为__名字的,子类不继承,子类不能访问
  • 如果在子类中向__名字赋值,那么会在子类中定义的一个与父类相同名字的属性
  • _名的变量、函数、类在使用from xxx import *时都不会被导入

  • 作者:辉辉咯
  • 原文链接:https://blog.csdn.net/qq_41020281/article/details/80198819
    更新时间:2022-10-21 09:57:27