zoukankan      html  css  js  c++  java
  • day_06、面向对象(二)

    isinstance和issubclass

    isinstance(obj.cls)检查obj是否是类cls的对象

    class Foo(object):
        pass
    
    obj = Foo()
    print(isinstance(obj, Foo))
    

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

    class Foo(object):
        pass
    
    class Bar(Foo):
        pass
    
    
    print(issubclass(Bar, Foo))
    

     反射

    1、什么是反射

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

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

    四个可以实现自省的函数

    下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

    def hasattr(*args, **kwargs): # real signature unknown
        """
        Return whether the object has an attribute with the given name.
        
        This is done by calling getattr(obj, name) and catching AttributeError.
        """
        pass
    hasattr
    def getattr(object, name, default=None): # known special case of getattr
        """
        getattr(object, name[, default]) -> value
        
        Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
        When a default argument is given, it is returned when the attribute doesn't
        exist; without it, an exception is raised in that case.
        """
        pass
    getattr
    def setattr(x, y, v): # real signature unknown; restored from __doc__
        """
        Sets the named attribute on the given object to the specified value.
        
        setattr(x, 'y', v) is equivalent to ``x.y = v''
        """
        pass
    setattr
    def setattr(x, y, v): # real signature unknown; restored from __doc__
        """
        Sets the named attribute on the given object to the specified value.
        
        setattr(x, 'y', v) is equivalent to ``x.y = v''
        """
        pass
    delattr
    class Foo:
        f = '类的静态变量'
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def say_hi(self):
            print("hi,{}. ".format(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, 'aaaa', '不存在的'))
    
    # 设置属性
    setattr(obj, 'sb', True)
    setattr(obj, 'show_name', lambda self:self.name + 'sb')
    print(obj.__dict__)
    print(obj.show_name)
    
    # 删除属性
    delattr(obj, 'age')
    delattr(obj, 'show_name')
    delattr(obj, "show_name111")
    
    print(obj,__dict__)
    四个方法的使用演示
    class Foo(object):
        staticField = "old boy"
    
        def __init__(self):
            self.name = "wupeiqi"
    
        def func(self):
            return "func"
    
        @staticmethod
        def bar():
            return 'bar'
    
    print(getattr(Foo, 'staticField'))
    print(getattr(Foo, 'func'))
    print(getattr(Foo, 'bar'))
    类也是对象
    import  sys
    
    def s1():
        print('s1')
    
    def s2():
        print('s2')
    
    this_moudle = sys.modules[__name__]
    print(hasattr(this_moudle, 's1'))
    print(hasattr(this_moudle, 's2'))
    反射当前模块成员

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

    #-*- coding:utf-8 -*-
    #version: 3.6.4
    
    def test():
        print('from the test')
    View Code
    #-*- coding:utf-8 -*-
    #version: 3.6.4
    
    """
    程序目录:
        module_test.py
        index.py
    
    当前文件:
        index.py
    """
    
    import module_test as obj
    
    print(hasattr(obj, 'test'))  # True
    getattr(obj, 'test')()       # from the test
    View Code

    __str__和__repr__

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

    自定制格式化字符串__format__

    format_dict={
        'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
        'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
        'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
    }
    
    class School:
        def __init__(self, name, addr, type):
            self.name = name
            self.addr = addr
            self.type = type
    
        def __repr__(self):
            return 'School(%s, %s)' % (self.name, self.addr)
    
        def __str__(self):
            return '(%s, %s)' %(self.name, self.addr)
    
        def __format__(self, format_spec):
            if not format_spec or format_spec not in format_dict:
                format_spec = 'nat'
            fmt = format_dict[format_spec]
            return fmt.format(obj=self)
    
    s1 = School('oldboy1', '北京', '私立')
    print('from repr: ', repr(s1))
    print('from str: ', str(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'))
    View Code
    class B:
        def __str__(self):
            return 'str: class B'
    
        def __repr__(self):
            return 'repr: class B'
    
    b = B()
    print('%s' %b)
    print('%r' %b)
    
    '''
    str: class B
    repr: class B
    '''
    %s 和 %r

    __del__

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

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

    class Foo:
    
        def __del__(self):
            print("执行我啦")
    
    f1 = Foo()
    del f1
    print('--->')
    
    '''
    执行我啦
    --->
    '''
    View Code

    item系列

    __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):
            self.__dict__.pop(item)
    
    f1 = Foo('sb')
    f1['age'] = 18
    f1['age1'] = 19
    print(f1.__dict__)
    
    
    del f1.age1
    print(f1.__dict__)
    del f1['age']
    f1['name'] = 'alex'
    print(f1.__dict__)
    
    '''
    {'name': 'sb', 'age': 18, 'age1': 19}
    {'name': 'sb', 'age': 18}
    del obj[key]时,执行我
    {'name': 'alex'}
    '''
    View Code

    __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)
    
    '''
    in new function
    in init function
    1
    '''
    View Code
    class Singleton:
    
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls, '_instance'):
                cls._instance = object.__new__(cls, *args, **kwargs)
            return cls._instance
    
    one = Singleton()
    two = Singleton()
    two.a = 3
    print(one.a)
    print(id(one))
    print(id(two))
    print(one is two)
    
    '''
    3
    89634128
    89634128
    True
    '''
    单例模式

    __call__

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

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

    class Foo:
        def __init__(self):
            pass
        def __call__(self, *args, **kwargs):
            print('__call__')
    
    obj = Foo()
    obj()         # 注释__call__方法 报错'Foo' object is not callable
    
    '''
    __call__
    '''
    View Code

    __len__

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

    __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))   # 注释掉__hash__不报错
    View Code

    __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
    
    a = A()
    b = A()
    print(a == b)   # 注释掉__eq__ False
    View Code
    import collections
    Card = collections.namedtuple('Card', ['rank', 'suit'])
    
    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 self.ranks
                                            for suit in self.suits]
    
        def __len__(self):
            return len(self._cards)
    
        def __getitem__(self, item):
            return self._cards[item]
    
    deck = FranchDeck()
    print(deck.__dict__)
    
    from  random import choice
    print(choice(deck))
    print(choice(deck))
    纸牌游戏
    import collections
    Card = collections.namedtuple('Card', ['rank', 'suit'])
    
    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 self.ranks
                                            for suit in self.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.__dict__)
    
    from  random import choice
    print(choice(deck))
    print(choice(deck))
    
    
    from random import shuffle
    shuffle(deck)
    print(deck[:5])
    纸牌游戏2

    懵逼

    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))
    

      

     
  • 相关阅读:
    idea 插件之 SequenceDiagram
    idea 中添加mybatis的mapper文件模板
    springBoot 中 logback配置文件详解
    Mysql show processlist、show profiles 排查问题
    input 输入框效验
    Java基础之comparator和comparable的区别以及使用
    mysql sql使用记录
    mysql 优化之索引的使用
    IDEA 中常用快捷键的使用
    form表单中method的get和post区别
  • 原文地址:https://www.cnblogs.com/kongzhou/p/9184540.html
Copyright © 2011-2022 走看看