伪私有属性的意义

  抛开语言层面,在通常的面向对象编程中(典型的C++),类都有私有属性。这是为了封装自己的属性,并且保证不会被外界调用修改而只能自己的方法调用修改。由于动态语言的特性,python中不存在严格封装特性,可以在外界随意调用类中任何属性和方法。一般我们想在类中申明一些不想被外界调用的私有属性时,通常约定俗成地会在属性名字的前面加上单下划线,如class._status.如果在使用别人写好的代码中看到了加了下划线的属性时,其实应该清楚最好不要调用甚至是修改它。

  在其它代码中有时还会看到属性名字的前面加上了双下划线,如果还想通过双下划线调用属性时就会报错,说没有这个属性。注意,这和单下划线不同。在类的作用域中,当解释器遇到以双下划线开头的属性时,会在双下划线前面加上类的名字。这样做的目的就很明确了,就是强制要求这个属性被外界调用,而且连继承它的类的实例也不能使用。说白了,连继承都不行。

class C1():
    def meth1(self):
        self.__x = ‘Hello World‘
    def meth2(self):
        print(self.__x)

class C2():
    def meth3(self):
        self.__o__x = ‘Hello Python‘
    def meth4(self):
        print(self.__o__x)

class C3(C1, C2):
    pass

c3 = C3()
c3.meth1()
c3.meth3()
c3.meth2()
c3.meth4()

输出为:

Hello World
Hello Python

再调用c3的__x:

c3.__x   # 如下所示,这个对象中没有__x这个属性

输出为:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-777a67f96b15> in <module>()
----> 1 c3.__x   # 如下所示,这个对象中没有__x这个属性

AttributeError: ‘C3‘ object has no attribute ‘__x‘

再执行:

print(dir(c3))   # 在下面中,注意看__x属性

输出为:

[‘_C1__x‘, ‘_C2__o__x‘, ‘__class__‘, ‘__delattr__‘, ‘__dict__‘, ‘__dir__‘, ‘__doc__‘, 

‘__eq__‘, ‘__format__‘, ‘__ge__‘, ‘__getattribute__‘, ‘__gt__‘, ‘__hash__‘, ‘__init__‘, 

‘__init_subclass__‘, ‘__le__‘, ‘__lt__‘, ‘__module__‘, ‘__ne__‘, ‘__new__‘, ‘__reduce__‘, 

‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘, 、

‘__weakref__‘, ‘meth1‘, ‘meth2‘, ‘meth3‘, ‘meth4‘]

总结

  在类中,加单下划线的属性可以被外界调用,但不推荐;加双下划线的属性更不能被外界调用,甚至继承它的类都不行。如果实在想调用,可以在双下划线前面加上_类的名字。这样就更不推荐,自己心里明白就行。

时间: 2024-10-15 21:41:02

伪私有属性的意义的相关文章

python的伪私有属性

伪私有属性 类Example中定义的变量__X会自动变成_Example__X, 变量前有双下划线的变量被称为伪私有属性,为什么叫伪私有属性呢?因为该属性并不是私有不可改变的,在类外依旧可以通过 _类名__变量名  来调用修改该属性,那为什么需要伪私有属性的存在呢?先举例一段代码来说明 1 class C1: 2 def meth1(self): 3 self.X=88 4 def meth2(self): 5 print(self.X) 6 7 class C2: 8 def metha(se

Python3基础 类的伪私有属性 __加变量名 的示例

镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.------------------------------------------ex1: code: class MyClass : #属性,公有的 height=10 weight=20 #伪私有属性 __haha=30; test=MyClass() print(test.__haha) result: ============= RESTART: C:\Users

伪私有属性 | 伪私有方法 | 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 面向对象 --- 私有属性和私有方法

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

06_私有属性和私有方法-python

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

Python私有属性和私有方法

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

私有属性和私有方法

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

3.5私有属性和私有方法

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

python基础===类的私有属性(伪私有)

说在前面的一点: python明明有私有的定义方法就是在变量或者方法的面前加上双下滑线__,这个实际上是python的伪私有.只是一种程序员约定俗称的规定,加了就表示私有变量,但是你如果要在外部调用的话,还是可以调用的. Python并没有真正的私有化支持,但可用下划线得到伪私有 (1)_xxx      "单下划线 " 开始的成员变量叫做保护变量,意思是只有类对象(即类实例)和子类对象自己能访问到这些变量,需通过类提供的接口进行访问:不能用'from module import *'