概要

在基类的定义中,如果有些属性或者方法,我们希望隐藏它,从而不被子类继承,或者使其不被实例直接访问到,这时候可以用到私有属性的命名方法。尽管类的所有属性和方法在某种意义上说都是“暴露的”,但是私有属性的存在即表达了我们的态度。

 


私有属性命名规则

在类中所有以双下划线开头的名称都会自动变形,比如一个私有属性名为 __print,会自动变形为 _Classname__print,这样就有效避免了在子类中使用的私有名称不会与基类中使用的相同私有名称发生冲突。示例代码如下:

# -*- coding: utf-8 -*-

class Marvel(object):
def __init__(self):
self.signature = self.__print()
def __print(self): # 私有实例方法,变形为 _Marvel__print
return "I love Marvel movies!" class EvilMarvel(Marvel):
def __init__(self):
super().__init__()
self.signature = self.__print()
self.base_signature = self.__base_print()
def __print(self): # 私有实例方法,变形为 _DC__print
return "I love DC movies!"
def __base_print(self):
return self._Marvel__print() # 强制调用父类的私有方法 a = Marvel()
print(a.signature) # 输出 I love Marvel movies!
print(a.__print()) # NameError: name '_Marvel__print' is not defined
print(a._Marvel__print()) # 强制访问,输出 I love Marvel movies! b = EvilMarvel()
print(b.signature) # 输出 I love DC movies!
print(b.base_signature) # 输出 I love Marvel movies!

尽管上述两个类别都有 __print 方法,实际调用时不会发生冲突,因为它们都在本身所属的类别中进行变形。当然,我们也可以强制性调用父类中的私有方法,比如 EvilMarvel 中的方法 __base_print,或者从外部强制访问私有属性,比如上述代码中倒数第五行,虽然语法上没任何问题,但是不建议这么做,这种做法也背离了设置私有属性的初衷。

 

单下划线在模块中的作用

单下划线在模块方法中也表示“私有”定义的命名,但它是防止通过 from moddule import * 语句导出名称,比如我们将上个示例代码中子类 EvilMarvel 前加一个下划线,并将文件名命名为 Marvel,再新建一个包含如下代码的文件,调用 _EvilMarvel 时会发生错误,

from Marvel import *

a = _EvilMarvel()
print(a.signature) # NameError: name '_EvilMarvel' is not defined

注意如果显示地引用单下划线开头的方法,则是可以的,比如

from Marvel import _EvilMarvel

a = _EvilMarvel()
print(a.signature) # 输出 I love DC movies!

另外可以通过定义模块中的列表 __all__,可以精确控制 from moddule import * 导入的名称集合,不过在此不作过多说明。

值得一提的是,这种单下划线的方式在类中,与普通属性名没有任何区别,不要混淆。

 


总结

Python 中的私有属性是一种通过添加双下划线的“伪”方法,这样可以避免父类与子类定义的对象之间发生命名空间冲突和暴露对象的内部实现,以及防止被实例对象直接访问得到,从而增强代码的健壮性。

Python 之私有属性的更多相关文章

  1. python 基础——私有属性

    私有属性 python 私有属性以两个下划线开头. python 私有属性只能在类内部访问,类外面访问会出错. python 私有属性之所以不能在外面直接通过名称来访问,其实质是因为 python 做 ...

  2. python 面向对象 私有属性

    __init__构造函数 self.name = name # 属性, 实例变量,成员变量,字段 def sayhi()# 方法, 动态属性 私有属性不对外看到 前面加上__ class role() ...

  3. python中私有属性的访问

    class MyClass(): def __init__(self): self.__superprivate = "Hello" self.__semiprivate = &q ...

  4. Python面向对象之私有属性和方法

    私有属性与私有方法 应用场景 在实际开发中,对象的某些属性或者方法 可能只希望在对象的内部被使用,而不希望在外部被访问到: 私有属性 就是对象不希望公开的属性: 私有方法 就是对象不希望公开的方法: ...

  5. Python - 私有属性(双下线的变形)

    __x会自动变形为_类名__x 正常情况 class A: def foo(self): print('from A') def test(self): self.foo() class B(A): ...

  6. Python 安全修改私有属性

    设置私有属性之后,如何修改私有属性 class Room: def __init__(self,name,length,width): self.__name = name self.__length ...

  7. Python全栈--9.1--面向对象进阶-super 类对象成员--类属性- 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理

    上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...

  8. Python的伪私有属性

    什么是伪私有属性? 在Python中,没有类似 private 之类的关键字来声明私有方法或属性. Python中要声明私有属性,需要在属性前加上双下划线(但是结尾处不能有双下划线),如:self._ ...

  9. python面向对象学习(三)私有属性和私有方法

    目录 1. 应用场景和定义方式 2. 伪私有属性和私有方法 在java或者其他的编程语言中,使用访问修饰符来限制属性和方法的访问级别,一般有public.protected.default.priva ...

随机推荐

  1. Objective-C的Runtime System

    [0] Outline --  [1] 版本和平台 --  [2] 与Runtime System交互 --  [3] 方法的动态决议 --  [4] 消息转发 --  [5] 类型编码 --  [6 ...

  2. Oracle 11g 数据类型

    1.     字符类型 数据类型 长度 说明 CHAR(n BYTE/CHAR) 默认1字节,n值最大为2000 末尾填充空格以达到指定长度,超过最大长度报错.默认指定长度为字节数,字符长度可以从1字 ...

  3. HTTP的学习记录3--HTTPS和HTTP

    一开始我所知道的只有HTTPS比HTTP更加安全,而且很多网站,如百度谷歌之流已经都是HTTPS了,博客园也是,你可以看到上方我们链接上那个绿色的小锁和绿色的安全二字. 另外吐槽一句,绿色还真是有趣, ...

  4. Proxy opening connection toSpringClound配置豪猪hystrixDashboard发生

    Proxy opening connection to: http://localhost:8001/hystrix.stream 配置hystrixDashboard发生的错误.一直在寻找 最后发现 ...

  5. Python----Anaconda + PyCharm + Python 开发环境搭建(使用pip,安装selenium,使用IDLE)

    1.Python开发中会用到的工具下载地址 FireBug插件安装地址:https://addons.mozilla.org/en-US/firefox/addon/firebug/ FirePath ...

  6. Spark Mllib里的如何对单个数据集用斯皮尔曼计算相关系数

    不多说,直接上干货! import org.apache.spark.mllib.stat.Statistics 具体,见 Spark Mllib机器学习实战的第4章 Mllib基本数据类型和Mlli ...

  7. VMware安装CentOS7的详细过程

    原文:https://www.jianshu.com/p/ce08cdbc4ddb?utm_source=tuicool&utm_medium=referral 本篇文章主要介绍了VMware ...

  8. Spring自动注入有关的注解

    Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. 1,@Comp ...

  9. jquery.validate+jquery.form表单验证提交

    1.通过jquery.validate的submitHandler选项,即当表单通过验证时运行回调函数.在这个回调函数中通过jquery.form来提交表单: <script type=&quo ...

  10. ssm(Spring、Springmvc、Mybatis)实战之淘淘商城-第十一天(非原创)

    文章大纲 一.课程介绍二.订单系统介绍三.项目源码与资料下载四.参考文章 一.课程介绍 一共14天课程(1)第一天:电商行业的背景.淘淘商城的介绍.搭建项目工程.Svn的使用.(2)第二天:框架的整合 ...