概要

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

 


私有属性命名规则

在类中所有以双下划线开头的名称都会自动变形,比如一个私有属性名为 __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. 洛谷P1349 广义斐波那契数列

    传送门 话说谁能告诉我矩阵怎么用latex表示…… 差不多就这样 //minamoto #include<iostream> #include<cstdio> #include ...

  2. Java Web之文件的上传及下载

    一.文件的上传 1. 简介 > 将一个客户端的本地的文件发送到服务器中保存. > 上传文件是通过流的形式将文件发送给服务器. 2.表单的设置 1.向服务器上传一个文件时,表单要使用post ...

  3. EasyUI/TopJUI之如何动态改变下拉列表框ComboBox输入框的背景颜色

    简单记录一下 前段时间接到客户需求:动态改变下拉列表框ComboBox输入框的背景颜色. 刚开始想的很简单在用户选择列表项的时候,判断一下列表框的value值添加相应的背景颜色就OK了,然而在实际操作 ...

  4. spring使用redisTemplate

    连接工厂:spring data redis 2.0中提供了两种redis客户端实现 LettuceConnectionFactory JedisConnectionFactory 区别: Lettu ...

  5. Jmeter ExcelDataPreProcessor

    Jmeter的预处理器主要是用来在采样器(sample)被执行之前做一些额外的工作,比如参数化等等. 本文写一个例子来说明如何增加一个预处理器,需求如下:我们想在执行采样器前读取Excel文件中的数据 ...

  6. sortable结合angularjs实现拖动排序

    记录拖动排序 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  7. Composite模式(组合设计模式)

    Composite 设计模式? 在计算机的文件系统中,有"文件夹"的概念(在有些操作系统(Linux操作系统)中,也称为"目录").文件夹里面既可以放入文件,也 ...

  8. BZOJ 4892 [Tjoi2017]dna 哈希+二分

    自己简直是傻死了...对于位置想错了... 二分出来的是LCP长度$+1$,即每一次二分出来的最后一个点都是失配的,而就算失配也会跳过这个点:所以当$k<=3$且模式串$s2$的指针$>l ...

  9. Luogu P3391 文艺平衡树(Splay or FHQ Treap)

    这道题要求区间反转...好东西.. 对于Splay:把l-1旋到根,把r+1旋到根的右儿子,这样r+1的左儿子就是整个区间了,然后对这个区间打个tg 注意要插-Inf和Inf到树里面,防止越界,坐标要 ...

  10. Tomcat从socket到java Servlet

    整体架构图 一. 启动阶段 BootStrap的main方法加载server.xml配置文件,封装成Server,Service,Connector,Engine等java对象 Server初始化== ...