十七、面相对象的进阶

简介: 内置方法 isinstance 只能判断是否为父子类的关系  不能判断爷爷和孙子的关系(False) issubclass 判断是否有继承关系    只要有继承关系都为真   class C: def func(self):pass class A(C): def f...

内置方法

isinstance 只能判断是否为父子类的关系  不能判断爷爷和孙子的关系(False)

issubclass 判断是否有继承关系    只要有继承关系都为真  

class C:
    def func(self):pass
class A(C):
    def func1(self):print(444)
class B(A):
    def func2(self):print(66)

print(issubclass(B,C))  B与C是继承关系   
print(isinstance(B,C))  B与C是继承关系不是父类与子类关系
#####
True
Flse

 反射

类中反射

对象反射

class A:
    b = '666'
    def func(self):
        print(333)
a = A()
print(getattr(A,'b'))   类反射
c = getattr(a,'func')   对象反射
d = c()
####
666
333

 

模块反射

 

 import  os
 getattr(os,'rename')('hehe','fuck')

  

自己反射

getattr和hasattr

 

import sys
def login():
    print('登陆成功')
def register():
    print('注册成功')
func = input('请输入')
if hasattr(sys.modules['__main__'],func):
    getattr(sys.modules['__main__'],func)()

 

  增删改对象的属性,和类的属性增删改

         setattr   delattr

class A:
bb = 'haha'
def __init__(self,name):
self.name = name

def wahaha(self):
print('wahahahahaha')

def qqxing(self):
print('qqqqqxing')

a = A('alex')
setattr(A,'qqxing',qqxing) 为类在增加动态属性
# setattr(a,'qqxing',qqxing) 为对象增加属性
print(A.__dict__)
print(a.__dict__)
a.qqxing()
delattr(A,'bb') 删除类的静态属性
delattr(A,'qqxing') 删除类的动态属性
print(A.__dict__)
a.qqing(a) 为对象增加的方法的调用方式,要传参
 

__str__    和   __repr__

这里需要说明的是,其实所有的输出我们能够看得见的都是在输出在文件上的,比如说cmd,pycharm 只不过是特殊的文件形式罢了,所以所有的print的结果都是字符串形式,只是每个不同的数据类型所在的类中的方法又做了不同的处理。我们平时在pycharm中正常的print可以打印出我们想要的东西,只不过是调用了别的类中的__str__的方法。而当我们定义一个类的时候,我们在类中print(对象名) 时,如果类中没有单独定义__str__  和__repr__的方法,则会调用父类object中的方法,而object中的__str__  和__repr__就是返回的内存地址。所以由此可见如果我们自己定义这些内置方法就可以输出我们想要的结果

class Teacher:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __str__(self):
        return "Teacher's object %s"%self.name
    def __repr__(self):
        return 'repr function %s'%self.name
a = Teacher('alex',80)
b = Teacher('egon',80)
print(str(a))
print(repr(a))
print(a)
print(b)
#####
Teacher's object alex
repr function alex
Teacher's object alex
Teacher's object egon
可以看到 当__str__ 和 __repr__同时存在时 print默认去找str方法
 

 

class Teacher:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    # def __str__(self):
    #     return "Teacher's object %s"%self.name
    def __repr__(self):
        return 'repr function %s'%self.name
a = Teacher('alex',80)
b = Teacher('egon',80)
print(str(a))
print(repr(a))
print(a)
print(b)
当我们把str方法注释掉的时候 print自动去找了repr的方法  而print(str())也去找了repr的方法

 

 

 

 

class Teacher:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __str__(self):
        return "Teacher's object %s"%self.name
    # def __repr__(self):
    #     return 'repr function %s'%self.name
a = Teacher('alex',80)
b = Teacher('egon',80)
print(str(a))
print(repr(a))
print(a)
print(b)
#####
acher's object alex
<__main__.Teacher object at 0x000002201ED825F8>
Teacher's object alex
Teacher's object egon

把repr的方法注释掉的时候,print都去找了str的方法,而print(repr())的方法直接去找了父类object的repr的方法打印了内存地址
我们的出来结论:  

 

 

 

 

1.当两种方法同时存在时,print默认去找str的方法
2,当str不存在的时候就都可以去找repr   包括print(str())
3,当repr不在时,正常的print都会找str  而print(repr())则会去找父类的repr 输出内存地址
4,repr是str的备胎   没有了str都可以用repr 都在时又不用他优先用str 

 

__new__  

设计模式:单例模式        就是一个类中只有一个实例

class B:
    __instance = None                        #定义一个实例
    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            obj = object.__new__(cls)     创建了一个新的空间赋给了__instance  这时候__instance不再是None  
            cls.__instance = obj
        return cls.__instance
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def func(self):
        print(self.name)
a = B('alex',80)
b = B('egon',20)
print(a)
print(b)
print(a.name)
print(b.name)
####
egon
egon
这段代码中 后面实例化都是在一个内存空间中进行所以 后面每次实例化新对象都是在一个内存空间 新的把旧的覆盖

 

 __item__

增删改

class Foo:
    def __init__(self,name):
        self.name=name
    def __getitem__(self,item):
        return  self.__dict__[item]
    def __setitem__(self, key, value):
        self.__dict__[key]=value
    def __delitem__(self, key):
        print('del obj[key]时,我执行')
        self.__dict__.pop(key)
a = Foo('aa')
print(a['name'])
a.age = 18
a['age'] = 22
a.age = 23
del a['age']
print(a.age)
f = Foo('alex')
# f.name = ...
print(f['name'])    # f.__getitem__('name')
f['age']  = 18      # 赋值
print(f.age)         # 自带的语法
print(f['age'])     # 修改
f['age']  = 80
print(f['age'])     # 通过实现__getitem__得到的
del f['age']
print(f.age)         # 删除

 

目录
相关文章
|
Java Maven Android开发
解决警告: Failed to scan JAR[...] java.util.zip.ZipException: error in opening zip file
解决警告: Failed to scan JAR[...] java.util.zip.ZipException: error in opening zip file
|
存储 安全 物联网
未来已来:区块链技术在物联网和虚拟现实中的创新应用
【8月更文挑战第1天】 随着科技的不断进步,新兴技术如区块链、物联网和虚拟现实正逐渐渗透到我们的生活中。本文将探讨这些技术的发展趋势和应用场景,以及它们如何相互融合,为我们的生活带来前所未有的便利和体验。我们将通过实际案例分析,深入探讨区块链技术在物联网和虚拟现实领域的创新应用,并展示相关代码示例。让我们一起探索这些新兴技术如何改变我们的世界。
|
JavaScript
性能工具之 FlameGraph 火焰图
其实很多类似 perf 的工具都能生成火焰图,像 systemtap/dtrace 之类的 并且这个思路,现在在 js 优化、代码优化等各方面都有具体的应用了 至于怎么理解? 简单点说,就是看谁又平又宽
362 7
性能工具之 FlameGraph 火焰图
|
JavaScript 前端开发 C++
vscode编辑器中如何调试nextjs代码
代码可调式的重要性不言而喻。 对于Programer来说,自己编写的程序能够被优雅调试是一件幸福的事情,特别是习惯了后端程序调试的开发者... 在折腾Nextjs项目的日子里,我走了很多弯路才弄明白在vs code中如何优雅的调试代码。
1260 1
vscode编辑器中如何调试nextjs代码
|
存储 算法
leetcode每日刷题
leetcode每日刷题
leetcode每日刷题
|
SQL XML 前端开发
关于Spring Boot那些你不知道的真相!
spring的时候,带一下spring boot,有时候出去面试,也会问到spring boot,提的一个点,spring boot启动的时候一个流程图,本身他是spring这个项目发展到一定阶段之后的一个产物。
191 0
|
人工智能 运维 安全
揭秘:宜信科技中心如何支持公司史上最大规模全员远程办公|下篇
分享宜信科技中心在保证呼叫中心远程办公方面的详细部署以及宜信科技中心在远程办公安全方面的关键举措。
【智力题】有多少残疾士兵?
有100个残疾兵.其中70名失去一只眼,75兵失去一只耳,80名失去一只手,85名失去一只脚。问:同时失去眼,耳,手,脚的兵至少有多少人?(可以有其他种类的残疾)答案:10人。(70+75-100+80-100+85-100)
1040 0