Python 之私有属性

概要

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


私有属性命名规则

在类中所有以双下划线开头的名称都会自动变形,比如一个私有属性名为 __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 中的私有属性是一种通过添加双下划线的“伪”方法,这样可以避免父类与子类定义的对象之间发生命名空间冲突和暴露对象的内部实现,以及防止被实例对象直接访问得到,从而增强代码的健壮性。

原文地址:https://www.cnblogs.com/zhoukui/p/10805710.html

时间: 2024-10-11 04:42:20

Python 之私有属性的相关文章

[有码有真相]python类私有属性等要点理解及测试示例代码

# encoding: utf-8 ''' 1. python约定类定义中"__"开头(至多一个"_"结尾)的属性为"相对"的私有属性 2. 私有属性在类及其子类定义中是"可见"的,在 其它范围正常访问是相对"不可见"的 3. 留下子类可以修改父类私有属性的口子方便debug测试等 4. 在类定义以外可以通过['_'+className+'私有属性名称']名称访问 5. 私有属性引入是避免类,实例等混淆和冲

Python 面向对象 --- 私有属性和私有方法

01,应用场景及定义方式 应用场景 在实际开发中,对象 的 某些属性或方法 可能只希望 在对象的内部被使用,而 不希望被外部访问到 私有属性 就是 对象 不希望公开的 属性 私有方法 就是 对象 不希望公开的 方法 定义方式 在 定义属性或方法时,在 属性名或者方法名前 增加连个下划线,定义的就是 私有 属性或方法 class Women: def __init__(self, name): self.name = name self.__age = 18 # def __secret(self

python中私有属性的访问

class MyClass(): def __init__(self): self.__superprivate = "Hello" self.__semiprivate = ", world!" mc=MyClass() print(mc._MyClass__semiprivate) 原文地址:https://www.cnblogs.com/c-x-a/p/8849714.html

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

__x会自动变形为_类名__x 正常情况 class A: def foo(self): print('from A') def test(self): self.foo() class B(A): def foo(self): print('from B') b = B() b.test() # from B 把foo定义成私有 class A: def __foo(self): #双下线私有属性在定义时就变形为_A__fa print('from A') def test(self): se

Python私有属性

1 访问类的私有属性首先我们定义一个包含私有属性的类,尝试使用实例对象访问它 [Python] 纯文本查看 复制代码 ? 1 2 3 4 5 6 7 8 class People(object):     def __init__(self):         self.__age = 20 people = People() print(people.__age) 结果如下: [Python] 纯文本查看 复制代码 ? 1 2 3 4 Traceback (most recent call l

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

上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数 面向对象三大特性:封装.继承和多态 本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 注意点: self ,我们讲过了,self = 对象,实例化后的对象调用类的各种成员的时候的self就是这个对象. 而且我们也讲过了

【python】-- 类的实例化过程、特征、共有属性和私有属性

实例化过程 1.类的定义和语法 class dog(object): #用class定义类 "dog class" #对类的说明 def __init__(self,name): #构造函数或者是构造方法,也可以叫初始化方法 self.name = name def sayhi(self): #类方法 "sayhi funcation" #对类方法的说明 print("hello,i am a dog,my name is ",self.name

伪私有属性 | 伪私有方法 | Python

1.私有属性 # 在属性前加上双下划线 # 为了保护属性安全 # 私有属性无法直接通过对象调用,需要添加一个调用方法来调用: class People(object): def __init__(self): self.__name = 'Mic' def get_private_attr(self, new_name): self.__name = new_name print(self.__name) # 创建对象 p = People() # 获取私有属性 p.get_private_at

python私有方法和私有属性属性理解

私有属性.方法--Python并没有真正的私有化支持,但可用下划线得到伪私有尽量避免定义以下划线开头的变量   (1)_xxx      "单下划线 " 开始的成员变量叫做保护变量,意思是只有类对象(即类实例)和子类对象自己能访问到这些变量,需通过类提供的接口进行访问:不能用'from module import *'导入   (2)__xxx    类中的私有变量/方法名 (Python的函数也是对象,所以成员方法称为成员变量也行得通.)," 双下划线 " 开始的