zoukankan      html  css  js  c++  java
  • python ==》 面向对象的反射,(isinstance and issubclass)

    1.staticmethod:(静态方法)

    静态方法:让类里的方法直接被类调用,就像正常的函数一样。

    class Staticmethod_Demo():
        role = 'Aray'
    
        @staticmethod
        def func():
            print('当普通方法用')
    Staticmethod_Demo.func()
    
    输出结果:
    当普通方法用

    2.classmethod:(类方法)

    类方法:默认参数为:cls  ,可以直接用类名调用,可以与类属性交互。

    class Classmethod_Demo():
        role = 'Aray'
    
        @classmethod
        def func(cls):
            print(cls.role)
    Classmethod_Demo.func()
    
    
    输出结果:
    Aray

    共同点:

      1.都可以直接被类调用,不需要实例化

    不同点:

      1,类方法必须有一个cls参数表示这这个类,静态方法不需要,不能直接被使用。

    绑定方法: 普通方法   类方法

    非绑定方法:  静态方法

    目前为止学的方法有:

      普通方法:默认有一个self对象传进来,并且只能被对象调用

      类方法:默认有一个cls传进来表示本类,并且可以被类和对象调用

      静态方法:没有默认参数,并且可以被类和对象调用。(这个方法不推荐使用)

    3.isinstance

    isinstance 作用是: 判断一个对象是不是这个类的对象,传两个参数,分别是对象和类,如果是,返回true,否则,为false。

    class Foo:
        pass
    class Son(Foo):
        pass
    s = Son()  #实例化
    print(isinstance(s,Son)) #判断一个对象是不是这个类的对象,传两个参数,分别是 对象和类
    print(isinstance(s,Foo))
    print(type(s) == Son)   #精准判断
    print(type(s) == Foo)
    
    输出结果:
    True
    True
    True
    False

    4.issubclass

    issubclass: 判断一个类是不是另一个类的子类,传两个参数,分别是子类和父类

    class Foo:
        pass
    class Son(Foo):
        pass
    s = Son()  #实例化
    
    print(issubclass(Son,Foo))  #判断一个类是不是另一个类的子类,传两个参数,分别是子类和父类
    print(issubclass(Son,object))
    print(issubclass(Son,Son))
    print(issubclass(Foo,object))
    print(issubclass(Foo,Son))
    
    输出结果:
    True
    True
    True
    True
    False
    

    5.logging模块

    logging的作用:1.不需要逐行注释      2.规范格式

    设置方式:

      1.config

      2.logger对象

    日志的级别等级: dubug,info,warning,error,critical

    logging:实操练习

    import logging
    logging.basicConfig(
        level = logging.DEBUG,      #设置级别为debug
        format = '%(name)s %(asctime)s [%(lineno)d]--%(message)s',
        datafmt = '%Y-%m-%d %H-%M%S‘,
    )
    logging,debug('debug')   
    logging.info('info)
    logging.warning('出错了!')
    
    #debug和info 是默认不会打印,等级太低,
    #这里因为上面降低了级别,所以结果才能显示出来。
    
    
    输出结果:
    root 2017-08-18 16-34-24 [34]-- debug       
    root 2017-08-18 16-34-24 [35]-- info 
    root 2017-08-18 16-34-24 [36]-- 出错了
    logging(1)

    输出结果:

    root 2017-08-18 17-01-40 [52]-- 出错了   
    
    注意:
    执行之后,会生成一个logging 文件,里面会又记载。(即又在屏幕输出,又在文件里生成)

    logger对象:解决即在屏幕输出,又在文件里生成,像上面一种仅能在屏幕输出打印,而不能在文件里生成。

    import logging
    def my_logger():
        logger = logging.getLogger()  
        file_handler = logging.FileHandler('logging',ending = 'utf-8')
        stream_handler = logging.StreamHandler()
        formatter = logging.Formatter(fmt = '%(name)s %(asctime) [%(lineno)d]--%(message)s' , datefmt = '%Y-%m-%d- %H-%M-%S')  #设置输出格式,可有可无
        file_handler.setFormatter(formatter)  #文件流
        stream_handler.setFormatter(formatter)  #屏幕流
        logger.addHandler(file_handler)
        logger.addHandler(stram_handler)
        return logger
    logger = my_logger()
    logger.warning('出错了')
    logger(2)

    2.logger对象,可以限制是就屏幕输出,还是在文件里生成。 logger可以灵活的运用。

    import  logging
    def my_logger(filename,file = True, stream =True):
        logger = logging.getLogger()
        formatter = logging.Formatter(fmt = '%(name)s %(asctime)s [%(lineno)d]-- %(message)s',datefmt='%Y-%m-%d %H-%M-%S')
        logger.setLevel(logging.DEBUG)  #指定日志打印的等级
        if file:
            file_handler = logging.FileHandler('logging',encoding='utf-8')
            file_handler.setFormatter(formatter)  #文件流
            logger.addHandler(file_handler)
    
        if stream:
            stream_handler=logging.StreamHandler()
            stream_handler.setFormatter(formatter)  #屏幕流
            logger.addHandler(stream_handler)
        return logger
    
    logger = my_logger('logging',file = False)   #限制在文件里生成。只在屏幕输出。
    logger.warning('出错了')
    logger.debug('debug')
    View Code

    输出结果:

    root 2017-08-18 17-04-00 [72]-- 出错了
    root 2017-08-18 17-04-00 [73]-- debug
    
    注意:
    这里是切到文件 logging 里 是没有记载的。因为给 False  了。

    二:反射

    反射:要求掌握 (多用在网络相关方面)。定义:可以用字符串的方式去访问对象的属性,调用对象的方法。

    常用:

      hasattr:

      getattr:

    hasattr和getattr通常是一起用的。一个检测,一个获取。

    class Black_one:
        feature = 'ugly'
        def __init__(self,name,addr):
            self.name = name
            self.affr = addr
    
        def sell_house(self):
            print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不是傻逼呢?'%self.name)
        def rent_house(self):
            print('%s 黑中介介绍租房子啦,傻逼才租啊'%self.name)
    
    b1 = Black_one('天地三清','道法无常')
    #检测是否含有属性
    print(hasattr(b1,'name'))
    print(hasattr(b1,'sell_house'))
    
    #获取属性
    n = getattr(b1,'name')
    print(n)
    func = getattr(b1,'sell_house')
    func()
    print(getattr(b1,'aaaa','不存在'))


    输出结果:
    True
    True
    天地三清
    天地三清 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不是傻逼呢?
    不存在

    不常用:

      setattr:

    #设置属性(新增)
    print(b1.__dict__)
    setattr(b1,'SB',True)
    setattr(b1,'time','1年')
    print(b1.__dict__)

    输出结果:{'name': '天地三清', 'addr': '道法无常'}
    {'name': '天地三清', 'addr': '道法无常', 'SB': True, 'time': '1年'}

      delattr:

    delattr(b1,'addr')
    delattr(b1,'time')
    print(b1.__dict__)
    
    输出结果:
    {'name': '天地三清', 'addr': '道法无常', 'SB': True, 'time': '1年'}
    {'name': '天地三清', 'SB': True}
    

    内置方法:

    str and repr

    class Foo:
        def __init__(self,name):
            self.name  = name
    
        def __str__(self):
            return '%s obj info in str'%self.name
    
        def __repr__(self):
            return 'obj info in repr'
    
    f = Foo('egon')
    print(f)
    print('%s'%f)
    print('%r'%f)
    
    输出结果:
    egon obj info in str
    egon obj info in str
    obj info in repr
    

    -del-:  如果没有手动删除,系统默认最后会del。

    class Foo:
        def __del__(self):
            print('执行我啊!')
    f = Foo()
    print(123)
    print(123)
    print(123)
    del f
    print(123)
    print(123)
    print(123)
    
    
    输出结果:
    123
    123
    123
    执行我啊!
    123
    123
    123
    

    item 系列:

    class Foo:
        def __init__(self):
            self.l = [1,2,3]
    
        def __getitem__(self, item):
            return self.l[item]
    
    f = Foo()
    print(f[0])
    print(f[1])
    print(f[2])
    
    输出结果:
    1
    2
    3
    
    class Foo:
        def __init__(self,name):
            self.name = 'aray'
            self.age = 12
            self.name = name             #这里对应的是下边的实例化所传的值,这个覆盖了上面的‘aray’。
        def __getitem__(self, item):
            return self.__dict__[item]
    f = Foo('zbk')
    print(f.__dict__)
    
    输出结果:
    {'name': 'zbk', 'age': 12}
    
    class Foo:
        def __init__(self,name):
            self.name = 'aray'
            self.age = 12
            self.name = name
        def __setitem__(self, key, value):   #设置值
            self.__dict__[key] = value
    
    f = Foo('zbk')
    f['name'] = 'alex'
    f['age'] = 12
    print(f.__dict__)
    
    输出结果:
    {'name': 'alex', 'age': 12}
    
    class Foo:
        def __init__(self,name):
            self.name = 'aray'
            self.age = 12
            self.name = name
        def __setitem__(self, key, value):
            self.__dict__[key] = value
    
        def __delitem__(self, key):     #删除的方法
            self.__dict__.pop(key)
    
    f = Foo('zbk')
    f['name'] = 'alex'
    f['age'] = 12
    print(f.__dict__)
    del f['age']
    print(f.__dict__)
    
    输出结果:
    {'name': 'alex', 'age': 12}
    {'name': 'alex'}
    

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

    __call__:

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

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

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

    __len__:

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __len__(self):
            return len(self.__dict__)
    a = A()
    print(len(a))

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

    __eq__:

    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)
    

      

  • 相关阅读:
    MySQL索引类型
    Spring+Quartz框架实现定时任务(集群,分布式)
    搭建Nginx+Java环境(转)
    windows环境下将csv文件导入mysql
    哈利波特折扣
    第二阶段个人总结06
    第二阶段个人总结05
    第二阶段个人总结04
    第二阶段个人总结03
    学习进度条——第13周
  • 原文地址:https://www.cnblogs.com/zhongbokun/p/7374951.html
Copyright © 2011-2022 走看看