Python私有机制(name mangling)(私有属性和私有方法)

一般面向对象编程都有公有(公开的,谁都可以用)和私有(自己私人的,不能给别人看的)的区分,像 C++、Java 中是通过 private、public 来区分公有和私有,但 python 中没有类似的关键字去声明。

默认上,对象的属性和方法都是公有的,我们可以通过 “.” 操作符来访问。

在 python 中,类是没有权限修饰的。但在实例开发中,可能希望对象的某些属性或方法只在对象的内部使用。所以为了实现这种类似私有变量的特征,python 采用了一种叫做 name mangling(名字改变或名字重整)的技术。这其实是伪私有。

定义私有属性和方法

在一个类中,定义私有属性或方法,只需要在属性名或者方法名前面加上 “__” 两个下划线,这个属性或方法就被定义成私有属性或私有方法了。

语法格式:

class Demo:
    # 私有属性
    __age = 15

    # 私有方法
    def __getName(self):
        pass

使用私有属性和私有方法可以保护数据,向使用者隐藏程序的核心开发细节。通常使用私有属性和私有方法做一些内部的事情。

访问私有属性和方法

在类的外部,私有属性和私有方法都是不能被直接访问的。如果在外界直接访问私有属性,程序会报错 AttributeError,告诉我们这个类的对象没有那个属性:

class Student:

    # 初始化方法
    def __init__(self, name, age):
        self.name = name
        # 私有属性
        self.__age = age

    # 私有方法
    def __getName(self):
        print(self.name)


stu = Student('张三', 21)

# __getName是私有方法,在外界无法访问
# stu.__getName() # AttributeError: 'Student' object has no attribute '__getName'

# __age是私有属性,不能被外部访问
print(stu.__age) # AttributeError: 'Student' object has no attribute '__age'
图片[1]-Python私有机制(name mangling)(私有属性和私有方法)-尤尤'blog

那么该如何在类的外界访问私有属性和私有方法呢?

1)间接访问:通过方法将私有属性返回,从而达到在外界访问私有属性的目的。

在对象的方法内部,可以通过 “self.私有属性名” 访问对象的私有属性。

所以我们可以通过 “self.私有属性名” 的方式在方法内部来访问私有属性,然后在外界调用在这个方法就可以达到在外界私有属性的目的了。

class Student:

    # 初始化方法
    def __init__(self, name, age):
        self.name = name
        # 私有属性
        self.__age = age

    def display(self):
        # 私有属性可以在类的内部访问:self.私有变量名
        print(f'我的名字叫{self.name},今年{self.__age}')

    # 私有方法,python将其更名为_Student__getName
    def __getName(self):
        print(self.name)

    # 私有属性在类内部可以被访问
    def getAge(self):
        return self.__age


stu = Student('张三', 21)
stu.display()
print(stu.getAge())
图片[2]-Python私有机制(name mangling)(私有属性和私有方法)-尤尤'blog

2)伪私有(_类名__名称)

在前面说过,Python 中的私有是伪私有,也就是说,在 Python 中,没有真正意义的私有。对于私有属性和私有方法,Python 解释器只是在给 属性或方法命名时,在名称前面加上 “_类名”(变成这样了,例如:_类名__名称),做了一个这样的特殊处理,才使得在外界无法直接访问私有属性和私有方法。

例如在 Student 类中定义属性 __age,python 就会将这个属性改名为 _Student__age(_类名__变量名)。在类里面依旧可以通过 self.__age 访问。

如果想要在类外部访问这个属性,需要通过 stu._Student__age(对象名._类名__变量名)来访问。

但是注意:在平时开发中,不建议使用这种方式来访问对象的私有属性或私有方法。因为那既然是对象的私有属性和方法,那就是对象的隐私,不建议在外界随便访问。

class Student:

    # 初始化方法
    def __init__(self, name, age):
        self.name = name
        # 私有属性,Python解释器将名称改为_Student__age
        self.__age = age

    def display(self):
        # 私有属性可以在类的内部访问:self.私有变量名
        print(f'我的名字叫{self.name},今年{self.__age}')

    # 私有方法,python将其更名为_Student__getName
    def __getName(self):
        print(self.name)


stu = Student('张三', 19)
stu.display()
# 私有属性,外界不能直接访问
print(stu._Student__age)
# 私有方法,外界不能直接调用
stu._Student__getName()
图片[3]-Python私有机制(name mangling)(私有属性和私有方法)-尤尤'blog

私有属性和私有方法是对象的隐私,不应该轻易在外界访问。

_ 下划线的几种情况

1)fun:不带下划线的变量和方法。

这是普通的变量和方法,只要是在作用域内都可以使用。

2)__fun__:前后都有两个下划线。

一般是 python 内置方法,如 __init__()。这些都是有特殊含义和特殊功能的,我们最好不要轻易自定义这种类型的变量或方法。

3)__fun:只有前面有两个下划线。

表示这是一个私有类型(private),只允许类本身访问。在外界不能直接访问,并且也不会被子类所继承,只能间接访问。

4)_fun:前面只有一个下划线。

表示这是一个保护类型(protected),允许该类本身和子类访问。也就是说它可以被子类继承,在类的外部也可以使用,但是如果换一个 py 文件,无法通过 “from xx import **” 来导入这种类型的变量或方法。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容