zoukankan      html  css  js  c++  java
  • python 之 面向对象(三)

    isinstance 和 issubclass

    class Foo:
        pass
    class Son(Foo):
        pass
    s =Son()
    #判断一个对象是不是这个类的对象,传两个参数(对象,类)
    print(isinstance (s,Son))
    print(isinstance (s,Foo))
    print(type(s) is Son)#Ture
    print(type(s) is Foo)#False 
    #isinstance he type 的区别,type可以做精准判断
    
    #判断一个类是不是另一个类的子类
    print(issubclass(Son,Foo))
    print(issubclass(Son,object))
    print(issubclass(Foo,object))
    print(issubclass(int,object))
    python 中所有类的父类都是object

    反射

    什么是反射

    反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)

    python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

    四个可以实现自省的函数

    hasattr getattr setattr delattr

    class Foo:
        def __init__(self):
            self.name = "egon"
            self.age = 73
        def func(self):
            print(123)
    egg = Foo()
    edd = Foo()
    #常用的hasattr
    #常用的getattr
    # print(hasattr(egg,'name'))#True
    # print(getattr(egg,'name'))#egon
    #先通过hasattr判断里面有没有,再用getattr取出来
    # if hasattr(egg,'func'):#如果存在返回属性值或者方法的内存地址,不存在报错
    #     q = getattr(egg,'func')#这两种方法常一起结合使用
    #     q()
    #不常用
    # setattr
    # setattr(egg,'sex','male')
    # print(egg.sex)
    def show_name(self):
        print( self.name+"sb")
    setattr(egg,'sh_name',show_name)
    
    egg.sh_name(egg)
    show_name(egg)
    egg.sh_name#这里是需要传参数的

    #delattr
    #delattr(egg,'name')
    #print(egg.name)
    class Foo:
        f = '类的静态变量'
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def say_hi(self):
            print('hi,%s'%self.name)
    obj = Foo('egon',73)
    #检查是否含有某属性,返回布尔值
    # print(hasattr(obj,'name'))
    # print(hasattr(obj,'say_hi'))
    
    #获取属性
    # n  = getattr(obj,'name')
    # print(n)
    # func = getattr(obj,'say_hi')
    # func()
    
    # print(getattr(obj,'www','没有'))#报错,这里的getattr有一个默认参数default可以赊着
    
    #设置属性
    setattr(obj,'sb',True)
    setattr(obj,'show_name',lambda self:self.name+'sb')
    print(obj.__dict__)
    print(obj.show_name(obj))
    
    #删除属性
    delattr(obj,'age')
    delattr(obj,'show_name')
    print(obj.__dict__)
    # delattr(obj,'show_name111')#不存在会报错
    class Foo(object):
        staticField = 'old boy'
        def __init__(self):
            self.name = "wupeiqi"
        def func(self):
            return 'func'
        @staticmethod
        def bar():
            return 'bar'
    print(Foo.bar())
    print(getattr(Foo,'staticField'))
    print(getattr(Foo,'func'))
    print(getattr(Foo,'bar'))
    import sys
    def s1():
        print('s1')
    def s2():
        print('s2')
    this_module = sys.modules[__name__]#查看当前模块
    
    print(hasattr(this_module,'s1'))
    print(getattr(this_module,'s2'))
    反射当前模块成员

    导入其它模块,利用反射查找该模块是否存在某个方法

    def test():
        print('from the test')
    my_module.py
    '''程序目录:
    my_module.py
    随笔.py
    当前文件:
    随笔.py'''
    import my_module as obj
    #obj.test()
    print(hasattr(obj,'test'))
    getattr(obj,'test')()
    随笔.py

    内置方法

    __str__ 和__repr__

    改变对象的字符串显示__str__,  __repr__

    自定制格式化字符串__format__

    class School:
        def __init__(self,name,addr,type):
            self.name = name
            self.addr = addr
            self.type = type
    
        def __str__(self):
            return 'School2(%s,%s)' % (self.name, self.addr)
        def __repr__(self):
            return 'School1(%s,%s)'%(self.name,self.addr)
        def __format__(self,format_spec):
            if not format_spec or format_spec not in format_dic:
                format_spec = 'tna'
            fmt = format_dic[format_spec]
            return fmt.format(obj =self)
    s1 = School('oldboy1','北京','私立')
    print('from %r'%s1)
    print('from %s'%s1)
    print(s1)
    '''
    str函数或者print函数---->obj.__str__()
    repr或者交互解释器---->obj.repr__()
    如果__str__没有被定义,那么就会使用__repr__来代替输入
    注意:这俩方法的返回值必须是字符串,否则抛出异常
    '''
    print(format(s1,'nat'))
    print(format(s1,"tna"))
    print(format(s1,"tan"))
    print(format(s1,"asfdasdffd"))
    '''当打印一个对象的时候,如果实现了str,打印str中的返回值
    当str没有被实现的时候,就会调用repr方法
    但是当你用字符串格式化的时候 %s和%r会分别去调用__str__和__repr__
    不管是在字符串格式化的时候还是在打印对象的时候,repr方法都可以作为str方法的替补
    但反之不行
    用于友好的表示对象。如果str和repr方法你只能实现一个:先实现repr
    '''

    __del__

    析构方法,当对象在内存中释放时,会自动触发执行。

    执行del 方法时调用__del__

    注:构析函数的调用是由解释器在进行垃圾回收自动触发执行的

    class Foo:
        def __del__(self):
            print('执行我啦')
    
    f = Foo()
    print(123)
    print(123)
    try:#使用try处理一下
        del f
        print(f)#NameError: name 'f' is not defined
    except NameError as e:
        print("name f 已经被删除了")
    finally:
        print(123)

    item系列

    __getitem__       __setitem__     __delitem__

    class Foo:
        def __init__(self):
            self.name = 'egon'
            self.age = 73
        def __getitem__(self, item):
            return self.__dict__[item]
        def __setitem__(self, key, value):
            self.__dict__[key] = value
        def __delitem__(self, key):
            del self.__dict__[key]
    f = Foo()
    print(f['name'])#egon
    f['name'] = 'alex'
    print(f.name)#alex
    del f['name']
    print(f.name)#AttributeError: 'Foo' object has no attribute 'name'
    f1 = Foo()
    print(f == f1)#False
    item系列

    __new__

    class A:
        def __init__(self):#调用init前先执行new方法
            print('in init function')
        def __new__(cls, *args, **kwargs):
            print('in new function')
            return object.__new__(A,*args,**kwargs)#new 方法必须有一个返回值
    a = A()
    b = A()
    c = A()
    d = A()

    object 将__new__()定义为静态方法,并且至少需要传递一个cls,cls表示需要实例化的类,此参数在实例化时由python解释器自动提供。

    实例化对象的时候,在调用__init__()方法之前,先调用了__new__()方法

    __new__()必须要有返回值,返回实例化出来的实例,需要注意的是,可以return父类__new__()出来的实例,也可以直接将object的__new__()出来的实例返回。

    __init__()有一个参数self,该self参数就是__new__()返回的实例,__init__()在__new__()的基础上才可以完成其它初始化动作,__init__()不需要返回值。

    若__new__()没有正确返回当前类的cls实例,那__init__()将不会被调用,即使是父类的实例也不行。

    单例模式

    单例模式是一种常用的设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例,单利对象就能派上用场。

    class Singleton:
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls,'a'):
                cls.a = object.__new__(cls,*args,**kwargs)
            return cls.a
    one = Singleton()
    two = Singleton()
    print(one,two)
    print(one == two)#True  one 就是 two
    # <__main__.Singleton object at 0x0128FBD0> <__main__.Singleton object at 0x0128FBD0>
    one.name = "alex"
    print(two.name)
    单例模式

     __call__

    对象后面加括号,触发执行。

    构造方法的执行是由创建对象触发的,即:对象 = 类名();而对于__call__方法的执行是由对象后加括号触发的,即:对象()或者类()

    # class Foo:
    #     def __init__(self):
    #         pass
    #     def __call__(self, *args, **kwargs):
    #         print('__call__')
    # obj = Foo()#执行__init__
    # obj()#__call__
    class Storage(dict):
        # __call__方法用于实例自身的调用
        #达到()调用的效果
        def __call__ (self, key):
             try:
                return self[key]
             except KeyError as k:
                 return None
    s = Storage()
    s['jjjk'] = 'aaaaa'#这里相当于添加了一个字典,调用key就会返回对应的value
    
    print (s('jjjk') )#调用__call__  返回aaaaa

    __len__

    # class A:
    #     def __init__(self):
    #         self.a = 1
    #         self.b = 2
    #         self.c = 3
    #     def __len__(self):
    #         return self.__dict__
    # a = A()
    # print(a.__len__())#{'a': 1, 'b': 2, 'c': 3}
    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
            self.c = 3
        def __len__(self):
            return len(self.__dict__)
    a = A()
    print(len(a))# 3

     __hash__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
        def __hash__(self):
            return hash(str(self.a)+str(self.b))
    a = A()
    print(a.__hash__())#相当于print(hash(a))

    __eq__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __eq__(self, other):
            if self.a == other.a and self.b == other.b:
                return True#False(这里可以实现定制)
    a = A()
    b = A()
    
    print(a == b)
  • 相关阅读:
    jsp grid can not be used in this ('quirks') mode
    weblogic stage更改不马上生效
    shell执行class或jar
    java json字符串与对象转换
    js对象及元素复制拷贝
    js中json字符串与对象的转换及是否为空
    js window.open隐藏参数提交
    poi excel文件名或者内容中文乱码
    linux poi生成excel demo调试附调用代码
    PeekMessage与GetMessage的对比
  • 原文地址:https://www.cnblogs.com/shengzhongqiu/p/7375673.html
Copyright © 2011-2022 走看看