Python私有属性及方法

1,690 阅读4分钟

这是我参与更文挑战的第 23 天,活动详情查看: 更文挑战

1. 概述

Python 对于类的成员没有严格的访问控制限制,默认可以公开访问。

那我们有些核心代码是属于机密的,不能提供给客户,但是也要帮客户要用,怎么办呢?

这个时候,我们想到了面向对象特征之一的封装。

面向对象特征

什么是封装?

封装指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部的操作和访问。

封装本质是一个种黑盒方式对于外界。只用对外界提供可以使用的接口,而不用关心其内部实现。

所以,封装有什么好处?

  • 隐藏类的实现细节
  • 让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入控制逻辑,限制属性的不合理访问
  • 可以进行数据检查,从而有利于保证对象信息的完整性
  • 便于修改,提高代码的可维护性

怎么是实现封装呢?

Python引入了私有属性和方法,将该隐藏的隐藏起来,不被外界访问。

好啦,xdm我们接下来学习私有属性和私有方法啦,小步快跑进场✌️

2. 私有属性(方法)介绍

私有属性和私有方法:

  1. 通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public).
  2. 类内部可以访问私有属性和方法
  3. 类外部不能直接访问私有属性(方法)
  4. 类外部可以通过__类名__私有属性(方法)名访问私有属性(方法)

注意:

方法本质上也是属性,只不过是可以通过()执行而已

3. 私有属性(方法)底层机制

python默认的成员函数和成员变量都是公开的,没有提供public、private等关键词来修饰

在python中我们定义私有变量或者方法是,需要在名字前加上__两个下划线。

在Python内部使用了一种 name mangling 技术,将 __membername替换成 _classname__membername,所以你在外部使用原来的私有成员的名字时,会提示找不到

我们来举个栗子:

class Animal:


    def __init__(self):
        self.__name = 'Tom'  # 私有属性
        self.age = 3


    def __get_name(self):  ##私有方法
        print("名字是{0}".format(self.__name))


    def get_age(self):  #普通方法,可以调用私有属性和方法
        print("{0} 的年龄是{1}".format(self.__name,self.age))


cat = Animal()
cat.get_age()
cat.__get_name() #实例直接访问私有方法会抛出异常

cat._Animal__get_name() # 实例直接调用Python内部改名之后的私有方法,就能正常访问

创建类

  1. 在堆内存中会创建Animal类.构造函数实例属性有公有属性age和私有属性__name;实例方法中__get_name私有方法和get_age公有方法

创建实例对象

  1. 通过Animal()创建cat实例,并且初始化实例属性,由于__name是私有属性,因此python内部会对该属性进行替换成_Animal__name.

私有方法被更改名字

  1. 同类私有方法也会被python内部更改名字。私有方法__get_name就会被更改成_Animal__get_name()。公有方法则不会被更改名字

私有方法运行结果

  1. 如我们执行上面代码结果。实例对象调用普通方法能正常执行,调用私有方法或者属性,Python内部则会抛出异常提示找不到

强制访问私有方法

  1. 如果我们要让外界访问私有方法或者属性,我们可以通过python改名之后进行访问_classname__私有方法(私有属性)。

详细说明

__name是私有属性,__get_name()是私有方法。

如果直接访问的话,会提示找不到相关的属性或者方法,但是如果你真要访问私 有的相关数据的话, 也是可以访问的,严格地说,私有方法在它们的类外是可以访问的,只是不容易处理。

在 Python 中没有什么是真正私有的;在内部,私有方法和属性的名字被忽然改变和恢复,以致于使得它们看上去用它们给定的名字是无法使用的

总结

Python并没有提供类似其他语言如C++等private修饰符,因此 Python并不能真正支撑隐藏。为了更好隐藏类成员,私有属性和私有方法。

私有属性和私有方法,可以更好提高代码的可维护性,便于修改,而不会影响公有的方法,我们在日常工作中,要多实践~

好啦,以上是本期内容,欢迎大佬在评论区指正,下次见