zoukankan      html  css  js  c++  java
  • 反射和内置方法

    我再也不想打气和每日金句了,我要吐了。

    断点的使用

    你用鼠标左键,去点代码的前面,也就是行数的后面,就会出现一个红点,大红点。

    然后运行debug,程序运行到这一行的时候,就会卡主,然后你就可以点下一步下一步,一步一步看了。很好用,贼好用,炸 弹好用。

    issubclass和isinstance的使用

    这个也很简单。

    issubclass的作用就是,判断一个类是不是另一个类的子类。具体用法如下

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

    False
    True
    True

    懂就好,别BB

    isinstance的作用就是判断一个对象是不是一个类实例化出来的

    #判断第一个参数是不是第二个参数的对象,返回true或者false
    class Foo:
        pass
    class Tt():
        pass
    
    f=Foo()
    print(isinstance(f,Foo))
    print(isinstance(f,Tt))
    
    

    True
    False

    反射

    用户输入一段字符串,执行该字符串对应的方法

    hasattr():判断一个属性是否在对象中,返回True或者False

    getattr():通过字符串获取属性或方法,如果获取到了,就会返回相应的属性或方法

    setattr():通过字符串来设置属性或方法# delattr():通过字符串来删除属性或方法

    以上的方法都是以字符串为基础的,你通过各种途径得到一个变量,变量值是一个字符串,所以不能通过以往的方式来执行操作了。

    hasattr()方法

    class Foo:
        def run(self):
            print('run')
        def speak(self):
            print('speak')
    
    
    p=Foo()
    cmd='speak'
    if hasattr(p,cmd):
        func=getattr(p,cmd)
        func()
    else:
        print('该命令不存在')
    

    speak

    setattr()方法

    #动态的往对象中放方法
    
    
    class Foo:
        def run(self):
            print('run')
        def speak(self):
            print('speak')
    
    
    p=Foo()
    def test(a):
        print(a)
    print(p.__dict__)
    key='name'
    value=test
    setattr(p,key,value)
    print(p.__dict__)
    p.name('nick')
    

    {}
    {'name': <function test at 0x000001B1F02DF048>}
    nick

    delattr()方法

    #动态的删除属性.
    class Foo:
        def run(self):
            print('run')
        def speak(self):
            print('speak')
    p=Foo()
    p.name='lqz'
    p.age=18
    p.sex='male'
    a=input('请输入要删除的属性:')
    print(p.__dict__)
    delattr(p,a)
    print(p.__dict__)
    

    请输入要删除的属性:age
    {'name': 'lqz', 'age': 18, 'sex': 'male'}
    {'name': 'lqz', 'sex': 'male'}

    内置方法

    我们之前学过的__init__方法,他是我们在实例化对象的时候会自动调用的方法,今天来讲一下其他的几个内置方法,这些__开头并且__结束的方法都是内置方法,也叫作魔法方法,你可以在面试的时候讲一下魔法方法,指不定酒吧面试官给整蒙逼了。

    __str__:如果不重写__str__ print打印会打印出内存地址,如果重写了,会打印出你想要的

    __repr__ : 跟str类似,在交互式命令下直接写变量名,会执行__repr__

    class Foo:
        def __init__(self,name):
            self.name=name
    
        def __str__(self):
            return '['+self.name+']'
    
    f=Foo('nick')
    print(f)
    

    [nick]

    当你使用了print,就会执行类里面的__str__方法,然后方法才返回,实际上你在打印的时候都是有调用这个方法的。当然,你如果去掉了这个方法,打印出来的就是这个对象的地址了。

    setattr,delattr,getattr(重要)

    这三个都是叫做点拦截方法

    如果去对象中取属性,一旦取不到,会进入到__getattr__

    如果去对象中赋值属性,一旦取不到,会进入到__setattr__

    如果删除对象中的属性,会进入__delattr__

    class Foo:
        def __init__(self,name):
            self.name=name
        def __getattr__(self, item):
            print('xxxx')
            return '你傻逼啊,没有这个字段'
    
        def __setattr__(self, key, value):
            print('yyyyy')
    
        def __delattr__(self, item):
            print('zzzzz')
    
    f=Foo('nick')
    print(f.age)
    print(f.__dict__)
    

    yyyyy
    xxxx
    你傻逼啊,没有这个字段
    {}

    我掐屌一算,你已经懵逼了,没错确实在调用不存在的属性的时候,才会调用getattr方法。那么既然这里调用到了,说明这个对象里面,一定没有name方法,那么为什么开始明明赋值了Nick,却没有呢?一开始赋值的时候,对象里面是没有name这个属性的,那么当你赋值不存在的属性的时候,就会调用setattr方法,这时候就只执行了这个方法,就结束了。并没有赋值。懂了吗?

    然后打印f.age,age有吗,没有,所以走getattr方法。

    delattr方法实例

    class Foo:
        def __init__(self,name):
            self.name=name
        def __getattr__(self, item):
            print('xxxx')
            return '你傻逼啊,没有这个字段'
    
        # def __setattr__(self, key, value):
        #     print('yyyyy')
    
        def __delattr__(self, item):
            print('zzzzz')
    
    f=Foo('nick')
    print(f.__dict__)
    del f.name
    print(f.__dict__)
    

    {'name': 'nick'}
    zzzzz
    {'name': 'nick'}

    相信这里细心的沙雕应该已经发现了我注释掉了setattr方法了,因为只要存在赋值情况,而且之前要是不存在这个属性,就一定会调用这个方法而且赋值这个操作就会失败了,所以我他妈没办法演示delattr这个方法!于是我只能把它注释了。

    del操作的时候就会调用delattr方法,其实我们看到的删除,都是在这个方法里进行的。但是在这里我们只是打印了zzzzz,没有删除,所以dict里面还是有name这个属性的。

    用非传统方法来取字典的值

    class Mydict(dict):
        def __init__(self,**kwargs):
            #
            super().__init__(**kwargs)
    
        def __getattr__(self, item):
            #
            # print(item)
            return self[item]
        def __setattr__(self, key, value):
            self[key]=value
    
    di=Mydict(name='lqz',age=18)
    print(di['name'])
    print(di.name)
    di.sex='male'
    print(di.sex)
    di['sex']='male'
    print(di.sex)
    
    

    lqz
    lqz
    male
    male

    我们看到的是,Mydict继承了dict类,并且在实例化对象的时候自动调用了父类的init方法,这就生成了一个字典,然后我们通过di['name']和di.name的方式都可以取到name的值,因为在调用name的时候,发现没有,就回去执行getattr方法,然后你就懂得了。

    #__item__系列  对象通过[] 中括号取值,赋值,删除值的时候,会调用
    class Foo:
        def __init__(self, name):
            self.name = name
        def __getitem__(self, item):
            name=getattr(self,item)
            # print(name)
            # print(self.__dict__[item])
            return name
            # return self.__dict__[item]
        def __setitem__(self, key, value):
            print('obj[key]=lqz赋值时,执行我')
            self.__dict__[key] = value
        def __delitem__(self, key):
            print('del obj[key]时,执行我')
            self.__dict__.pop(key)
    #
    f=Foo('nick')
    print(f['name'])
    
    

    只要通过中括号来搞事情,那就会调用getitem或者setitem或者delitem。不多bb了。。

    #__call__   对象加括号会调用它
    class Foo:
        def __call__(self):
            print('xxxx')
    
    f=Foo()
    f()
    

    懂?

    #__enter__和__exit__
    #上下文管理器,本质原来
    # with open() as f:
    #     pass
    
    

    这个我不懂,明天再说

    糟了,今天讲得太正经了。

  • 相关阅读:
    springcloud之Feign(五)
    ElasticSearch
    SpringCloud之Hystrix介绍
    SpringCloud之Ribbon负载均衡(四)
    springcloud之Eureka集群配置(三)
    Problem08 输入数字求和
    Problem07 处理字符串
    Problem06 求最大公约数及最小公倍数
    Problem05 判断分数等级
    Problem04 分解质因数
  • 原文地址:https://www.cnblogs.com/chanyuli/p/11449481.html
Copyright © 2011-2022 走看看