Python 私有变量
所谓私有变量,是指通过某种手段,使得对象中的属性或方法无法被外部所访问。属于Python的保护机制。
1.定义私有变量
定义私有变量可以在变量名前加上两个 "_",来表示(这里说的私有变量并不是真正的私有,而是尽量避免从外部进行访问)
-
class C: #定义类C
-
def __init__(self,x): #定义带参构造函数
-
self.__x = x #定义私有变量
-
def set_x(self,x): #定义set_x方法,设置私用变量的值
-
self.__x = x
-
def get_x(self): #定义get_x方法,获取私有变量的值
-
print(self.__x)
-
-
-
c = C(22)
-
c.__x #从外部访问私有变量会报错
-
'''
-
Traceback (most recent call last):
-
File "<pyshell#16>", line 1, in <module>
-
c.__x
-
AttributeError: 'C' object has no attribute '__x'
-
'''
-
c.get_x() #调用内部方法,访问私有变量
-
# 22
-
c.set_x(33)
-
c.get_x()
-
# 33
上述代码可知,我们从外部访问私有变量会产生错误,因为想访问私有变量的值,就需要通过指定的借口,通过调用内部的方法来实现访问私有变量。如果想从外部访问私有变量,我们可以利用Python的强访问方法—— name mangling机制 ,也就是名字改编。代码如下:
-
c.__dict__ #通过内省,查看实例对象中的数据
-
# {'_C__x': 33}
我们看到会得到{'_C__x': 33}的结果,也就是_类名__私有变量名,我们调用一下可以访问的到私有变量的值。
-
c._C__x
-
# 33
同样的,属性可以通过强访问的方式访问到,方法也是可以的,代码如下:
-
class Si:
-
def __funA(self): #定义私有方法
-
print("我是私有方法")
-
-
-
s = Si()
-
s.__funA()
-
'''
-
Traceback (most recent call last):
-
File "<pyshell#34>", line 1, in <module>
-
s.__funA()
-
AttributeError: 'Si' object has no attribute '__funA'
-
'''
-
s._Si__funA() #强访问
-
# 我是私有方法
2. 动态添加属性
在对象诞生之后,通过动态添加属性的方式来添加私有变量。
-
c.__y = 250 向实例对象中添加数据
-
c.__dict__
-
-
# {'_C__x': 22, '__y': 250}
通过内省可以看到实例对象中有 __y 这个属性值,并且可以直接访问的到。并没有变成 _C__y 的形式,说明名字改编是发生在类实例化对象的时候的事情,之后添加的属性不会发生改变。
3. 与下划线相关的变量
一个单横线开头的变量:通常是仅供内部使用的变量,不要随便的访问和试图修改。
一个单横线结尾的变量:一般用于要定义的变量名是属于Python关键字以及其他内部变量时,强制使用。(其实没啥用~)
-
def funA():
-
for_ = 100
-
print(for_)
-
-
-
funA()
-
-
-
# 100
4. 效率提升 __slots__
当我们在实例对象中添加一个不存在的变量的时候,可以借助字典来完成,通过这种方法会很方便的向实例对象中添加数据,不过会浪费大量的存储空间。
-
class A: #定义类A
-
def __init__(self,x): #构造方法__init__
-
self.x = x
-
-
-
a = A(10) #对x进行赋值
-
a.x
-
# 10
-
a.y = 20 #向实例对象中添加属性y
-
a.y
-
# 20
-
a.__dict__ #查看实例对象中的属性值
-
# {'x': 10, 'y': 20}
-
-
a.__dict__['z'] = 30 #向实例对象中添加不存在的属性 z
-
a.z
-
# 30
-
a.__dict__
-
# {'x': 10, 'y': 20, 'z': 30}
这时Python就提供了一个叫做__slots__的类属性,避免了采用字典来存放造成空间上的浪费。采用这个方法可以限制类能使用的属性。
-
class B:
-
__slots__["x","y"] #限制该类中只能定义 x和y属性
-
def __init__(self,x):
-
self.x = x
-
-
b = B(20)
-
b.x
-
# 20
-
b.y = 30
-
b.y
-
# 30
-
b.z = 40 #像实例对象中加入__slots__中没有规定的数据时,会报错
-
-
#'B' object has no attribute 'z'
这种限制不仅体现在动态添加属性上面,如果我们想在类的内部创建一个__slots__中不包含的属性,也是不被允许的。
-
class B:
-
__slots__["x","y"] #限制该类中只能定义 x和y属性
-
def __init__(self,x,y,z):
-
self.x = x
-
self.y = y
-
self.z = z
-
-
b = B(20,30,40)
-
-
#'B' object has no attribute 'z'
__slots__类属性,使对象划分一个固定大小的空间来存放指定的属性,避免了利用字典来存放造成空间上的浪费(列表中的名称 用来限制类使用的属性)。
5.继承中的__slots__
对于继承在父类的__slots__属性,不会在子类中生效,Python只会关注各个具体的类中定义的__slots__属性。
-
class B:
-
__slots__["x","y"] #限制该类中只能定义 x和y属性
-
def __init__(self,x):
-
self.x = x
-
-
class C(B): #定义类C,继承类 B
-
pass
-
-
c = C(20)
-
c.x
-
# 20
-
c.y = 30
-
c.y
-
# 30
-
c.z = 40 #定义继承类中不存在的属性
-
c.z
-
# 40 可以输出创建的属性值
-
c.__slots__
-
# ['x','y']
-
c.__dict__
-
# {'z',40}
-
对于继承的类中有__slots__属性时,父类中的属性会存放再__slots__中,而子类新添加的属性会存放在__dict__中。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhghbbge
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13