记录黑客技术中优秀的内容,传播黑客文化,分享黑客技术精华

深入类与对象-中

2021-01-31 23:06



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

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

使用代码:

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面向对象编程

http://www.langzi.fun/Python%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%BC%96%E7%A8%8B.html

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

数据封装与私有属性

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

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

比如:

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 : <function magic.run at 0x0000018AB312CC80>
__dict__ :
 <attribute '__dict__' of 'magic' objects>
__weakref__ : <attribute '__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__查看。



知识来源: https://mp.weixin.qq.com/s?__biz=MjM5Nzk3NTIwOA==&mid=2247484062&idx=4&sn=981d5a5914aea6699c5327a7a08d36e5&chksm=a6d0875991a70e4f48a8f9278709ab147afb45368c5b4480c28f23432c12fe0040f758817dfc&scene=27&k

阅读:145688 | 评论:0 | 标签:无

想收藏或者和大家分享这篇好文章→复制链接地址

“深入类与对象-中”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

黑帝公告 📢

永久免费持续更新精选优质黑客技术文章Hackdig,帮你成为掌握黑客技术的英雄

广而告之 💖

标签云 ☁