python 私有属性_全面深入理解 Python 类与对象

(点击上方公众号,可快速关注一起学Python)

作者:浪子燕青       链接:

http://www.langzi.fun/深入类与对象-中.html

类属性和实例属性查找顺序

属性:在内部定义的方法或者变量

使用代码:

class magic:
a = 'langzi'
def __init__(self,x):
self.x = x
# 这里传入的x已经属于这个对象

def run(self):
return self.x

m = magic('xx')
m.a = 'LANGZILANGZI'
print(m.a)
# 查找实例的属性
print(magic.a)
# 查找类的属性
print(m.x)
# 查找实例的属性

返回结果:

'LANGZILANGZI'
'langzi'
'xx'

查找顺序是由下而上的查找顺序,init是初始化实例的属性,要记住这里使用magic.x是会报错的,因为init是初始化实例,这个实例成为m,并不在属于magic。

可能这样举例子不清晰,重新再看看代码

class magic:
name = '浪子'
def __init__(self,name):
self.name = name

m = magic('langzi')
print(m.name)
print(magic.name)

返回结果:

langzi
浪子

这样是不是就比较清晰了,类中的name=’浪子’是属于magic类当中的,实例m.name是属于实例m当中的,是在类中init初始化的属性。

他们的查找顺序是这样:

  1. 找m.name的时候,由下而上,会先找到m。

  2. 找到m的初始话对象,从init开始查找,就会找到初始化传入的name

  3. 如果init中没有name的话,就会往上走,查找类中是不是存在name

就好像这样的代码:

class magic:
# def __init__(self,name):
# self.name = name
name = '浪子'

m = magic()
print(m.name)
print(magic.name)

返回结果:

浪子
浪子

三大方法

python类的调用有三大方法,分别是类方法,静态方法,实例方法。这三个方法在曾经的文章有说过。

Python面向对象编程

这里就不多做代码重写,去原链接查看学习即可。

数据封装与私有属性

私有属性,也叫私有方法,是以双下划线开头的命名变量。

无法通过实例方法和子类来调用的,只能通过类中写的方法来调用。

比如:

class magic:
__user = '浪子'

a = magic
print(magic.__user)
print(a.__user)

加了双下划线的user就是私有属性,是没法通过下面两种方式进行调用的,唯一可以调用这个私有属性的方法就是使用类方法。

class magic:
__user = '浪子'
@classmethod
def run(cls):
print(cls.__user)

magic.run()

只有这样才能调用类的私有属性,这也就是对数据做了一个很好的封装。

但是这样的封装并不是完全安全的,比如你看下面的代码:

class magic:
__user = '浪子'

m = magic
print(m._magic__user)

这样能直接调用user,说白了这是一个小技巧python把私有变量偷偷隐藏起来变成了这样子。

python的自省机制

自省:通过一定的机制,查询到对象的内部结构

使用__dict__方法查询类的属性:

class magic:
'我是注释'
user = '浪子'
def run(age):
print(age)

for x,y in magic.__dict__.items():
print(x,':',y)

返回结果:

__module__ : __main__
__doc__ : 我是注释
user : 浪子
run : 0x0000018AB312CC80>
__dict__ : '__dict__' of 'magic' objects>
__weakref__ : '__weakref__' of 'magic' objects>

通过dict来获取类的内部结果,记住通过magic.__dict__[‘user’]=’小桃红’也可以动态操作属性。

不仅仅是dict,通过dir可以更加强大的列出该类的所有属性。

super函数

super函数,调用父类。在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现。

class A:
def __init__(self,name):
self.name = name
def run(self):
print(self.name+'6666666')

class B(A):
def __init__(self,name):
self.name = name
def run(self):
print(self.name+'7777777')
super().run()
#这里是调用父类的run()方法
# 还可以这样super().__init__(name=name)这样的格式

c = B('浪子')
c.run()

返回对象:

浪子7777777
浪子6666666

事实上,super 和父类没有实质性的关联,super(cls, inst) 获得的是 cls 在 inst 的 MRO 列表中的下一个类。MRO则是python中类继承关系选择的一种,有点像是广度优先原则,可以print m.__mro__查看。

(完)

看完本文有收获?请转发分享给更多人

关注「Python那些事」,做全栈开发工程师

66706b251da189f672a032a6b7c9b68d.png

推荐阅读

  • 爬虫非专业八级模拟考试

  • 我们不再需要 Chrome 了?

  • 为什么Python不用设计模式?

  • 用Python发一个高逼格的朋友圈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值