• python之路_面向对象进阶


    一、内置函数isinstance和issubclass

    1、isinstance()

      isinstance(obj,cls)检查obj是否是类 cls 的对象,类似type()。

    class Foo(object):
        pass
    obj = Foo()
    print(isinstance(obj, Foo))      #输出结果:True
    
    print(isinstance(10,int))        #输出结果:True

      sinstance() 与 type() 区别:type() 不会认为子类是一种父类类型,不考虑继承关系。sinstance() 会认为子类是一种父类类型,考虑继承关系。

    class A:
        pass
    class B(A):
        pass
    isinstance(A(), A)              # returns True
    type(A()) == A                  # returns True
    isinstance(B(), A)              # returns True
    type(B()) == A                  # returns False

    (2)issubclass()

      issubclass(sub, super)检查sub类是否是 super 类的派生类/子类

    class Foo(object):
        pass
    class Bar(Foo):
        pass
    print(issubclass(Bar, Foo))    #输出结果:True

    二、反射相关

      python面向对象中的反射:通过字符串的形式操作对象相关的属性。如下为4个可以实现自省的函数:

    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'))     #输出结果:True
    print(hasattr(obj,'say_hi'))             #输出结果:True
    
    #获取属性
    n=getattr(obj,'name')
    print(n)                                 #输出结果:egon
    func=getattr(obj,'say_hi')
    func()                                   #输出结果:hi,egon
    
    
    #设置属性
    setattr(obj,'sb',True)
    setattr(obj,'show_name',lambda self:self.name+'sb')
    print(obj.__dict__)                      #输出结果:{'name': 'egon', 'age': 73, 'sb': True, 'show_name': <function <lambda> at 0x00000194A8817048>}
    print(obj.show_name(obj))
    
    #删除属性
    delattr(obj,'age')
    delattr(obj,'show_name')
    
    print(obj.__dict__)                      #输出结果:{'name': 'egon', 'sb': True}

     三、类的内置方法

    1、__str__和__repr__

      改变对象的字符串显示__str__,__repr__,这俩方法的返回值必须是字符串,否则抛出异常。

    class Animal:
        def __init__(self,kind,name):
            self.kind = kind
            self.name = name
    
        def __str__(self):
            return 'str : %s : %s'%(self.kind,self.name)
    
        def __repr__(self):
            return 'repr : %s : %s'%(self.kind,self.name)
    cat = Animal('cat','guolei')
    print(str(cat))                               #输出结果:str : cat : guolei
    print(repr(cat))                              #输出结果:repr : cat : guolei
    print('%s'%cat)                               #输出结果:str : cat : guolei
    print('%r'%cat)                               #输出结果:repr : cat : guolei

     2、__del__

      析构方法,当对象在内存中被释放时,自动触发执行。注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

    class Foo:
    
        def __del__(self):
            print('执行我啦')
    
    f1=Foo()
    del f1                                        #输出结果:执行我啦

    3、__getitem__\__setitem__\__delitem__

    class Foo:
        def __init__(self,name):
            self.name=name
    
        def __getitem__(self, item):
            print(self.__dict__[item])
    
        def __setitem__(self, key, value):
            self.__dict__[key]=value
        def __delitem__(self, key):
            print('del obj[key]时,我执行')
            self.__dict__.pop(key)
        def __delattr__(self, item):
            print('del obj.key时,我执行')
            self.__dict__.pop(item)
    
    f1=Foo('sb')
    f1['age']=18
    f1['age1']=19
    del f1.age1                                          #输出结果:del obj.key时,我执行
    del f1['age']                                        #输出结果:del obj[key]时,我执行
    f1['name']='alex'
    print(f1.__dict__)                                   #输出结果:{'name': 'alex'}

    4、__new__

    class A:
        def __init__(self):
            self.x = 1
            print('in init function')
        def __new__(cls, *args, **kwargs):
            print('in new function')
            return object.__new__(A, *args, **kwargs)
    
    a = A()
    print(a.x)

    单例模式:

      无论实例化多少个对象,只有一个对象存在,且这个对象为最后实例化的那个对象。

    #实例1:
    class Singleton:
        def __new__(cls, *args, **kw):
            if not hasattr(cls, '_instance'):
                orig = super(Singleton, cls)
                cls._instance = orig.__new__(cls, *args, **kw)
            return cls._instance
    
    one = Singleton()
    two = Singleton()
    two.a = 3
    print(one.a)# 3
    # one和two完全相同,可以用id(), ==, is检测
    print(id(one))                                          # 29097904
    print(id(two))                                          # 29097904
    print(one == two)                                       # True
    print(one is two)                                       # True
    class Teacher:
        __instance=None
        def __new__(cls, *args, **kwargs):
            if not cls.__instance:
                cls.__instance=object.__new__(cls)
            return cls.__instance
        def __init__(self,name,cloth):
            self.name=name
            self.cloth=cloth
    刘老师=Teacher('liu','bai')
    王老师=Teacher('wang','hei')
    print(刘老师.name)                                     #输出结果:wang
    print(刘老师.cloth)                                    #输出结果:cloth

    5、__call__

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

    class Foo:
        def __init__(self):
            pass
        def __call__(self, *args, **kwargs):
            print('__call__')
    obj = Foo()                                         # 执行 __init__
    obj()                                               # 执行 __call__

    6、__len__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __len__(self):
            return len(self.__dict__)
    a = A()
    print(len(a))                                      #输出结果:2

    7、__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(hash(a))                                    #输出结果:3429960989477292991

    8、

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __eq__(self,obj):
            if  self.a == obj.a and self.b == obj.b:
                return True
    a = A()
    b = A()
    print(a == b)                                    #输出结果为:True

    四、相关例题

    1、纸牌游戏1:抽牌

    class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = ['红心','方板','梅花','黑桃']
    
        def __init__(self):
            self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
                                            for suit in FranchDeck.suits]
    
        def __len__(self):
            return len(self._cards)
    
        def __getitem__(self, item):
            return self._cards[item]
    
    deck = FranchDeck()
    print(deck[0])
    from random import choice
    print(choice(deck))
    print(choice(deck))

    2、纸牌游戏2:洗牌

    class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = ['红心','方板','梅花','黑桃']
    
        def __init__(self):
            self._cards = [(rank,suit) for rank in FranchDeck.ranks
                                            for suit in FranchDeck.suits]
    
        def __len__(self):
            return len(self._cards)
    
        def __getitem__(self, item):
            return self._cards[item]
    
        def __setitem__(self, key, value):
            self._cards[key] = value
    
    deck = FranchDeck()
    print(deck[0])
    from random import shuffle
    shuffle(deck)
    print(deck[:5])

    3、一道面试题

    class Person:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def __hash__(self):
            return hash(self.name+self.sex)
    
        def __eq__(self, other):
            if self.name == other.name and self.sex == other.sex:return True
    
    
    p_lst = []
    for i in range(84):
        p_lst.append(Person('egon',i,'male'))
    
    print(p_lst)
    print(set(p_lst))
  • 相关阅读:
    缺少动态连接库.so--cannot open shared object file: No such file or directory
    BST删除节点
    python中列表字典和字符串的相互转化
    浅谈WM算法
    MySql--主从复制
    python中的__getattr__(self, name)浅谈
    Linux下python路径查找不到的解决办法
    Python闭包和装饰器
    Python操作Mysql数据库
    MySQL----联结
  • 原文地址:https://www.cnblogs.com/seven-007/p/7583446.html
Copyright © 2020-2023  润新知