十七、面相对象的进阶

简介: 内置方法 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)         # 删除

 

目录
相关文章
|
5月前
|
前端开发 JavaScript 程序员
一文搞懂:关于Defferred对象知识详解
一文搞懂:关于Defferred对象知识详解
73 0
|
6月前
|
存储 程序员 C++
C++系列十七:类与对象
C++系列十七:类与对象
|
6月前
|
前端开发
前端知识笔记(四)———深浅拷贝的区别,如何实现?
前端知识笔记(四)———深浅拷贝的区别,如何实现?
58 0
|
JavaScript 前端开发
【重温基础】12.使用对象 上
【重温基础】12.使用对象 上
151 0
|
JavaScript 前端开发
十二、面向对象实战之封装拖拽对象【上】
前面几篇文章,我跟大家分享了JavaScript的一些基础知识,这篇文章,将会进入第一个实战环节:利用前面几章的所涉及到的知识,封装一个拖拽对象。为了能够帮助大家了解更多的方式与进行对比,我会使用三种不同的方式来实现拖拽。 •不封装对象直接实现; •利用原生JavaScript封装拖拽对象; •通过扩展jQuery来实现拖拽对象。 本文的例子会放置于codepen.io[1]中,供大家在阅读时直接查看。如果对于codepen不了解的同学,可以花点时间稍微了解一下。
136 0
十二、面向对象实战之封装拖拽对象【上】
|
JavaScript 前端开发
十二、面向对象实战之封装拖拽对象【下】
前面几篇文章,我跟大家分享了JavaScript的一些基础知识,这篇文章,将会进入第一个实战环节:利用前面几章的所涉及到的知识,封装一个拖拽对象。为了能够帮助大家了解更多的方式与进行对比,我会使用三种不同的方式来实现拖拽。 •不封装对象直接实现; •利用原生JavaScript封装拖拽对象; •通过扩展jQuery来实现拖拽对象。 本文的例子会放置于codepen.io[1]中,供大家在阅读时直接查看。如果对于codepen不了解的同学,可以花点时间稍微了解一下。
215 0
|
网络架构
【重温基础】12.使用对象 下
【重温基础】12.使用对象 下
110 0
|
Java 索引
链表数据“暗杀记” | 带你学《Java面向对象编程》之九十四
本节将为读者展示如何实现查询一个数据在链表中是否存在以及如何去删除一个数据或全部数据的功能。
链表数据“暗杀记” | 带你学《Java面向对象编程》之九十四
|
Java 索引
链表实战之宠物商店 | 带你学《Java面向对象编程》之九十五
本节结合在宠物商店出售各种宠物的实际情景,制定宠物、宠物店的标准并进行实现,结合链表实现对商店内宠物的动态数据操作。
链表实战之宠物商店 | 带你学《Java面向对象编程》之九十五
|
Java 索引
速度了解神奇的索引操作 | 带你学《Java面向对象编程》之九十三
本节带领读者实现了根据索引取数据和修改数据的操作,并对这些操作进行了简单的复杂度分析。
速度了解神奇的索引操作 | 带你学《Java面向对象编程》之九十三